Non-uniform-width characters are now properly handled (modulo bugs).
This commit is contained in:
parent
74edf72cde
commit
fc78fbeb3e
|
@ -245,6 +245,56 @@ impl 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;
|
||||||
|
let mut iter = self.as_str().graphemes(true);
|
||||||
|
|
||||||
|
for _ in range(0, index) {
|
||||||
|
if let Some(g) = iter.next() {
|
||||||
|
let w = grapheme_vis_width_at_vis_pos(g, pos);
|
||||||
|
pos += w;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
panic!("Line::grapheme_index_to_vis_pos(): index past end of line.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Translates a visual horizontal position to the closest grapheme index
|
||||||
|
pub fn vis_pos_to_closest_grapheme_index(&self, vis_pos: uint) -> uint {
|
||||||
|
let mut pos = 0;
|
||||||
|
let mut i = 0;
|
||||||
|
let mut iter = self.as_str().graphemes(true);
|
||||||
|
|
||||||
|
while pos < vis_pos {
|
||||||
|
if let Some(g) = iter.next() {
|
||||||
|
let w = grapheme_vis_width_at_vis_pos(g, pos);
|
||||||
|
if (w + pos) > vis_pos {
|
||||||
|
let d1 = vis_pos - pos;
|
||||||
|
let d2 = (pos + w) - vis_pos;
|
||||||
|
if d2 < d1 {
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pos += w;
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Returns an immutable string slice into the text block's memory
|
/// Returns an immutable string slice into the text block's memory
|
||||||
pub fn as_str<'a>(&'a self) -> &'a str {
|
pub fn as_str<'a>(&'a self) -> &'a str {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -828,6 +878,34 @@ fn text_line_split_beginning() {
|
||||||
assert!(tl2.ending == LineEnding::CRLF);
|
assert!(tl2.ending == LineEnding::CRLF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn grapheme_index_to_closest_vis_pos_1() {
|
||||||
|
let tl = Line::new_from_str("Hello!");
|
||||||
|
|
||||||
|
assert!(tl.grapheme_index_to_closest_vis_pos(0) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn grapheme_index_to_closest_vis_pos_2() {
|
||||||
|
let tl = Line::new_from_str("\tHello!");
|
||||||
|
|
||||||
|
assert!(tl.grapheme_index_to_closest_vis_pos(1) == TAB_WIDTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn vis_pos_to_closest_grapheme_index_1() {
|
||||||
|
let tl = Line::new_from_str("Hello!");
|
||||||
|
|
||||||
|
assert!(tl.vis_pos_to_closest_grapheme_index(0) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn vis_pos_to_closest_grapheme_index_2() {
|
||||||
|
let tl = Line::new_from_str("\tHello!");
|
||||||
|
|
||||||
|
assert!(tl.vis_pos_to_closest_grapheme_index(TAB_WIDTH) == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
// LineGraphemeIter tests
|
// LineGraphemeIter tests
|
||||||
|
|
|
@ -89,10 +89,29 @@ impl Buffer {
|
||||||
return self.root.pos_2d_to_closest_1d_recursive(pos);
|
return self.root.pos_2d_to_closest_1d_recursive(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn pos_vis_2d_to_closest_1d(&self, pos: (uint, uint)) -> uint {
|
||||||
|
if pos.0 >= self.line_count() {
|
||||||
|
return self.len();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let gs = self.pos_2d_to_closest_1d((pos.0, 0));
|
||||||
|
let h = self.get_line(pos.0).vis_pos_to_closest_grapheme_index(pos.1);
|
||||||
|
return gs + h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn pos_1d_to_closest_2d(&self, pos: uint) -> (uint, uint) {
|
pub fn pos_1d_to_closest_2d(&self, pos: uint) -> (uint, uint) {
|
||||||
return self.root.pos_1d_to_closest_2d_recursive(pos);
|
return self.root.pos_1d_to_closest_2d_recursive(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn pos_1d_to_closest_vis_2d(&self, pos: uint) -> (uint, uint) {
|
||||||
|
let (v, h) = self.root.pos_1d_to_closest_2d_recursive(pos);
|
||||||
|
let vis_h = self.get_line(v).grapheme_index_to_closest_vis_pos(h);
|
||||||
|
return (v, vis_h);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Insert 'text' at grapheme position 'pos'.
|
/// Insert 'text' at grapheme position 'pos'.
|
||||||
|
|
196
src/editor.rs
196
src/editor.rs
|
@ -6,6 +6,32 @@ use files::{load_file_to_buffer, save_buffer_to_file};
|
||||||
use string_utils::grapheme_count;
|
use string_utils::grapheme_count;
|
||||||
|
|
||||||
|
|
||||||
|
/// A text cursor. Also represents selections when range.0 != range.1.
|
||||||
|
///
|
||||||
|
/// `range` is a pair of 1d grapheme indexes into the text.
|
||||||
|
///
|
||||||
|
/// `vis_start` is the visual 2d horizontal position of the cursor. This
|
||||||
|
/// doesn't affect editing operations at all, but is used for cursor movement.
|
||||||
|
pub struct Cursor {
|
||||||
|
pub range: (uint, uint), // start, end
|
||||||
|
pub vis_start: uint, // start
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Cursor {
|
||||||
|
pub fn new() -> Cursor {
|
||||||
|
Cursor {
|
||||||
|
range: (0, 0),
|
||||||
|
vis_start: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_vis_start(&mut self, buf: &Buffer) {
|
||||||
|
let (v, h) = buf.pos_1d_to_closest_2d(self.range.0);
|
||||||
|
self.vis_start = buf.get_line(v).grapheme_index_to_closest_vis_pos(h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pub struct Editor {
|
pub struct Editor {
|
||||||
pub buffer: Buffer,
|
pub buffer: Buffer,
|
||||||
pub file_path: Path,
|
pub file_path: Path,
|
||||||
|
@ -16,7 +42,7 @@ pub struct Editor {
|
||||||
pub view_pos: (uint, uint), // (line, col)
|
pub view_pos: (uint, uint), // (line, col)
|
||||||
|
|
||||||
// The editing cursor position
|
// The editing cursor position
|
||||||
pub cursor: (uint, uint), // (line, col)
|
pub cursor: Cursor,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,7 +55,7 @@ impl Editor {
|
||||||
dirty: false,
|
dirty: false,
|
||||||
view_dim: (0, 0),
|
view_dim: (0, 0),
|
||||||
view_pos: (0, 0),
|
view_pos: (0, 0),
|
||||||
cursor: (0, 0),
|
cursor: Cursor::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +68,7 @@ impl Editor {
|
||||||
dirty: false,
|
dirty: false,
|
||||||
view_dim: (0, 0),
|
view_dim: (0, 0),
|
||||||
view_pos: (0, 0),
|
view_pos: (0, 0),
|
||||||
cursor: (0, 0),
|
cursor: Cursor::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,35 +86,38 @@ impl Editor {
|
||||||
|
|
||||||
/// Moves the editor's view the minimum amount to show the cursor
|
/// Moves the editor's view the minimum amount to show the cursor
|
||||||
pub fn move_view_to_cursor(&mut self) {
|
pub fn move_view_to_cursor(&mut self) {
|
||||||
|
let (v, h) = self.buffer.pos_1d_to_closest_vis_2d(self.cursor.range.0);
|
||||||
|
|
||||||
// Horizontal
|
// Horizontal
|
||||||
if self.cursor.1 < self.view_pos.1 {
|
if h < self.view_pos.1 {
|
||||||
self.view_pos.1 = self.cursor.1;
|
self.view_pos.1 = h;
|
||||||
}
|
}
|
||||||
else if self.cursor.1 >= (self.view_pos.1 + self.view_dim.1) {
|
else if h >= (self.view_pos.1 + self.view_dim.1) {
|
||||||
self.view_pos.1 = 1 + self.cursor.1 - self.view_dim.1;
|
self.view_pos.1 = 1 + h - self.view_dim.1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vertical
|
// Vertical
|
||||||
if self.cursor.0 < self.view_pos.0 {
|
if v < self.view_pos.0 {
|
||||||
self.view_pos.0 = self.cursor.0;
|
self.view_pos.0 = v;
|
||||||
}
|
}
|
||||||
else if self.cursor.0 >= (self.view_pos.0 + self.view_dim.0) {
|
else if v >= (self.view_pos.0 + self.view_dim.0) {
|
||||||
self.view_pos.0 = 1 + self.cursor.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) {
|
pub fn insert_text_at_cursor(&mut self, text: &str) {
|
||||||
let pos = self.buffer.pos_2d_to_closest_1d(self.cursor);
|
|
||||||
let str_len = grapheme_count(text);
|
let str_len = grapheme_count(text);
|
||||||
let p = self.buffer.pos_2d_to_closest_1d(self.cursor);
|
|
||||||
|
|
||||||
// Insert text
|
// Insert text
|
||||||
self.buffer.insert_text(text, pos);
|
self.buffer.insert_text(text, self.cursor.range.0);
|
||||||
self.dirty = true;
|
self.dirty = true;
|
||||||
|
|
||||||
// Move cursor
|
// Move cursor
|
||||||
self.cursor = self.buffer.pos_1d_to_closest_2d(p + str_len);
|
self.cursor.range.0 += str_len;
|
||||||
|
self.cursor.range.1 += str_len;
|
||||||
|
self.cursor.update_vis_start(&(self.buffer));
|
||||||
|
|
||||||
|
// Adjust view
|
||||||
self.move_view_to_cursor();
|
self.move_view_to_cursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,67 +128,127 @@ impl Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_text_behind_cursor(&mut self, grapheme_count: uint) {
|
pub fn remove_text_behind_cursor(&mut self, grapheme_count: uint) {
|
||||||
let pos_b = self.buffer.pos_2d_to_closest_1d(self.cursor);
|
let pos_b = self.cursor.range.0;
|
||||||
let pos_a = if pos_b >= grapheme_count {pos_b - grapheme_count} else {0};
|
let pos_a = if pos_b >= grapheme_count {pos_b - grapheme_count} else {0};
|
||||||
|
let tot_g = pos_b - pos_a;
|
||||||
// Move cursor
|
|
||||||
self.cursor = self.buffer.pos_1d_to_closest_2d(pos_a);
|
|
||||||
|
|
||||||
// Remove text
|
// Remove text
|
||||||
self.buffer.remove_text(pos_a, pos_b);
|
self.buffer.remove_text(pos_a, pos_b);
|
||||||
|
|
||||||
self.dirty = true;
|
self.dirty = true;
|
||||||
|
|
||||||
|
// Move cursor
|
||||||
|
self.cursor.range.0 -= tot_g;
|
||||||
|
self.cursor.range.1 -= tot_g;
|
||||||
|
self.cursor.update_vis_start(&(self.buffer));
|
||||||
|
|
||||||
|
// Adjust view
|
||||||
|
self.move_view_to_cursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_text_in_front_of_cursor(&mut self, grapheme_count: uint) {
|
||||||
|
let pos_a = self.cursor.range.1;
|
||||||
|
let pos_b = if (pos_a + grapheme_count) <= self.buffer.len() {pos_a + grapheme_count} else {self.buffer.len()};
|
||||||
|
|
||||||
|
// Remove text
|
||||||
|
self.buffer.remove_text(pos_a, pos_b);
|
||||||
|
self.dirty = true;
|
||||||
|
|
||||||
|
// Move cursor
|
||||||
|
self.cursor.update_vis_start(&(self.buffer));
|
||||||
|
|
||||||
|
// Adjust view
|
||||||
|
self.move_view_to_cursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_text_inside_cursor(&mut self) {
|
||||||
|
// If selection, remove text
|
||||||
|
if self.cursor.range.0 < self.cursor.range.1 {
|
||||||
|
self.buffer.remove_text(self.cursor.range.0, self.cursor.range.1);
|
||||||
|
self.dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move cursor
|
||||||
|
self.cursor.range.1 = self.cursor.range.0;
|
||||||
|
self.cursor.update_vis_start(&(self.buffer));
|
||||||
|
|
||||||
|
// Adjust view
|
||||||
self.move_view_to_cursor();
|
self.move_view_to_cursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cursor_to_beginning_of_buffer(&mut self) {
|
pub fn cursor_to_beginning_of_buffer(&mut self) {
|
||||||
self.cursor = (0, 0);
|
self.cursor.range = (0, 0);
|
||||||
|
self.cursor.update_vis_start(&(self.buffer));
|
||||||
|
|
||||||
|
// Adjust view
|
||||||
|
self.move_view_to_cursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cursor_to_end_of_buffer(&mut self) {
|
pub fn cursor_to_end_of_buffer(&mut self) {
|
||||||
self.cursor = self.buffer.pos_1d_to_closest_2d(self.buffer.len()+1);
|
let end = self.buffer.len();
|
||||||
|
self.cursor.range = (end, end);
|
||||||
|
self.cursor.update_vis_start(&(self.buffer));
|
||||||
|
|
||||||
|
// Adjust view
|
||||||
|
self.move_view_to_cursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cursor_left(&mut self) {
|
pub fn cursor_left(&mut self, n: uint) {
|
||||||
let p = self.buffer.pos_2d_to_closest_1d(self.cursor);
|
if self.cursor.range.0 >= n {
|
||||||
|
self.cursor.range.0 -= n;
|
||||||
if p > 0 {
|
|
||||||
self.cursor = self.buffer.pos_1d_to_closest_2d(p - 1);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
self.cursor = self.buffer.pos_1d_to_closest_2d(0);
|
self.cursor.range.0 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.move_view_to_cursor();
|
self.cursor.range.1 = self.cursor.range.0;
|
||||||
}
|
self.cursor.update_vis_start(&(self.buffer));
|
||||||
|
|
||||||
pub fn cursor_right(&mut self) {
|
|
||||||
let p = self.buffer.pos_2d_to_closest_1d(self.cursor);
|
|
||||||
self.cursor = self.buffer.pos_1d_to_closest_2d(p + 1);
|
|
||||||
|
|
||||||
|
// Adjust view
|
||||||
self.move_view_to_cursor();
|
self.move_view_to_cursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cursor_up(&mut self) {
|
pub fn cursor_right(&mut self, n: uint) {
|
||||||
if self.cursor.0 > 0 {
|
if self.cursor.range.1 <= (self.buffer.len() - n) {
|
||||||
self.cursor.0 -= 1;
|
self.cursor.range.1 += n;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
self.cursor.range.1 = self.buffer.len();
|
||||||
|
}
|
||||||
|
|
||||||
|
self.cursor.range.0 = self.cursor.range.1;
|
||||||
|
self.cursor.update_vis_start(&(self.buffer));
|
||||||
|
|
||||||
|
// Adjust view
|
||||||
|
self.move_view_to_cursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cursor_up(&mut self, n: uint) {
|
||||||
|
let (v, _) = self.buffer.pos_1d_to_closest_vis_2d(self.cursor.range.0);
|
||||||
|
|
||||||
|
if v >= n {
|
||||||
|
self.cursor.range.0 = self.buffer.pos_vis_2d_to_closest_1d((v - n, self.cursor.vis_start));
|
||||||
|
self.cursor.range.1 = self.cursor.range.0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
self.cursor_to_beginning_of_buffer();
|
self.cursor_to_beginning_of_buffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Adjust view
|
||||||
self.move_view_to_cursor();
|
self.move_view_to_cursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cursor_down(&mut self) {
|
pub fn cursor_down(&mut self, n: uint) {
|
||||||
if self.cursor.0 < (self.buffer.line_count() - 1) {
|
let (v, _) = self.buffer.pos_1d_to_closest_vis_2d(self.cursor.range.0);
|
||||||
self.cursor.0 += 1;
|
|
||||||
|
if v < (self.buffer.line_count() - n) {
|
||||||
|
self.cursor.range.0 = self.buffer.pos_vis_2d_to_closest_1d((v + n, self.cursor.vis_start));
|
||||||
|
self.cursor.range.1 = self.cursor.range.0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
self.cursor_to_end_of_buffer();
|
self.cursor_to_end_of_buffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Adjust view
|
||||||
self.move_view_to_cursor();
|
self.move_view_to_cursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,35 +256,29 @@ impl Editor {
|
||||||
if self.view_pos.0 > 0 {
|
if self.view_pos.0 > 0 {
|
||||||
let move_amount = self.view_dim.0 - (self.view_dim.0 / 8);
|
let move_amount = self.view_dim.0 - (self.view_dim.0 / 8);
|
||||||
if self.view_pos.0 >= move_amount {
|
if self.view_pos.0 >= move_amount {
|
||||||
if self.cursor.0 >= move_amount {
|
|
||||||
self.cursor.0 -= move_amount;
|
|
||||||
}
|
|
||||||
self.view_pos.0 -= move_amount;
|
self.view_pos.0 -= move_amount;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if self.cursor.0 >= self.view_pos.0 {
|
|
||||||
self.cursor.0 -= self.view_pos.0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
self.cursor_to_beginning_of_buffer();
|
|
||||||
}
|
|
||||||
self.view_pos.0 = 0;
|
self.view_pos.0 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.cursor_up(move_amount);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
self.cursor_to_beginning_of_buffer();
|
self.cursor_to_beginning_of_buffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Adjust view
|
||||||
self.move_view_to_cursor();
|
self.move_view_to_cursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn page_down(&mut self) {
|
pub fn page_down(&mut self) {
|
||||||
|
// TODO
|
||||||
let nlc = self.buffer.line_count() - 1;
|
let nlc = self.buffer.line_count() - 1;
|
||||||
|
|
||||||
if self.view_pos.0 < nlc {
|
if self.view_pos.0 < nlc {
|
||||||
let move_amount = self.view_dim.0 - (self.view_dim.0 / 8);
|
let move_amount = self.view_dim.0 - (self.view_dim.0 / 8);
|
||||||
let max_move = nlc - self.view_pos.0;
|
let max_move = nlc - self.view_pos.0;
|
||||||
let cursor_max_move = nlc - self.cursor.0;
|
|
||||||
|
|
||||||
if max_move >= move_amount {
|
if max_move >= move_amount {
|
||||||
self.view_pos.0 += move_amount;
|
self.view_pos.0 += move_amount;
|
||||||
|
@ -204,14 +287,13 @@ impl Editor {
|
||||||
self.view_pos.0 += max_move;
|
self.view_pos.0 += max_move;
|
||||||
}
|
}
|
||||||
|
|
||||||
if cursor_max_move >= move_amount {
|
self.cursor_down(move_amount);
|
||||||
self.cursor.0 += move_amount;
|
}
|
||||||
}
|
else {
|
||||||
else {
|
self.cursor_to_end_of_buffer();
|
||||||
self.cursor_to_end_of_buffer();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Adjust view
|
||||||
self.move_view_to_cursor();
|
self.move_view_to_cursor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,19 +87,19 @@ impl TermUI {
|
||||||
},
|
},
|
||||||
|
|
||||||
K_UP => {
|
K_UP => {
|
||||||
self.editor.cursor_up();
|
self.editor.cursor_up(1);
|
||||||
},
|
},
|
||||||
|
|
||||||
K_DOWN => {
|
K_DOWN => {
|
||||||
self.editor.cursor_down();
|
self.editor.cursor_down(1);
|
||||||
},
|
},
|
||||||
|
|
||||||
K_LEFT => {
|
K_LEFT => {
|
||||||
self.editor.cursor_left();
|
self.editor.cursor_left(1);
|
||||||
},
|
},
|
||||||
|
|
||||||
K_RIGHT => {
|
K_RIGHT => {
|
||||||
self.editor.cursor_right();
|
self.editor.cursor_right(1);
|
||||||
},
|
},
|
||||||
|
|
||||||
K_ENTER => {
|
K_ENTER => {
|
||||||
|
@ -151,6 +151,7 @@ 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);
|
||||||
|
|
||||||
|
@ -163,8 +164,7 @@ impl TermUI {
|
||||||
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_1d = editor.buffer.pos_2d_to_closest_1d(editor.cursor);
|
let cursor_pos = editor.buffer.pos_1d_to_closest_2d(editor.cursor.range.0);
|
||||||
let cursor_pos = editor.buffer.pos_1d_to_closest_2d(cursor_pos_1d);
|
|
||||||
let print_cursor_pos = (cursor_pos.0 + editor.view_pos.0, cursor_pos.1 + editor.view_pos.1);
|
let print_cursor_pos = (cursor_pos.0 + editor.view_pos.0, cursor_pos.1 + editor.view_pos.1);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
@ -207,7 +207,7 @@ 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 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 cursor_pos_1d >= editor.buffer.len() {
|
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, " ");
|
self.rb.print(print_cursor_pos.1, print_cursor_pos.0, rustbox::RB_NORMAL, Color::Black, Color::White, " ");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
3
todo.md
3
todo.md
|
@ -1,6 +1,3 @@
|
||||||
- Proper handling of non-uniform-width characters. Specifically, this needs
|
|
||||||
to address tabs. But it should be done to handle the general case anyway,
|
|
||||||
since that's unlikely to be more complex and will future-proof things.
|
|
||||||
- Line number display
|
- Line number display
|
||||||
- Editor info display (filename, current line/column, indentation style, etc.)
|
- Editor info display (filename, current line/column, indentation style, etc.)
|
||||||
- File opening by entering path
|
- File opening by entering path
|
||||||
|
|
Loading…
Reference in New Issue
Block a user