WIP: fixes for long line support.

This commit is contained in:
Nathan Vegdahl 2015-02-15 23:23:17 -08:00
parent ecf91607ac
commit 0bc809781d
2 changed files with 28 additions and 7 deletions

View File

@ -316,6 +316,7 @@ impl Line {
pub fn grapheme_iter<'a>(&'a self) -> LineGraphemeIter<'a> { pub fn grapheme_iter<'a>(&'a self) -> LineGraphemeIter<'a> {
LineGraphemeIter { LineGraphemeIter {
graphemes: self.text.grapheme_iter(), graphemes: self.text.grapheme_iter(),
grapheme_count: None,
ending: self.ending, ending: self.ending,
done: false, done: false,
} }
@ -326,6 +327,18 @@ impl Line {
pub fn grapheme_iter_at_index<'a>(&'a self, index: usize) -> LineGraphemeIter<'a> { pub fn grapheme_iter_at_index<'a>(&'a self, index: usize) -> LineGraphemeIter<'a> {
LineGraphemeIter { LineGraphemeIter {
graphemes: self.text.grapheme_iter_at_index(index), graphemes: self.text.grapheme_iter_at_index(index),
grapheme_count: None,
ending: self.ending,
done: false,
}
}
/// Returns an iterator over the graphemes of the line
pub fn grapheme_iter_at_index_with_max_length<'a>(&'a self, index: usize, length: usize) -> LineGraphemeIter<'a> {
LineGraphemeIter {
graphemes: self.text.grapheme_iter_at_index(index),
grapheme_count: Some(length),
ending: self.ending, ending: self.ending,
done: false, done: false,
} }
@ -422,6 +435,7 @@ pub const LINE_ENDINGS: [&'static str; 9] = ["",
/// An iterator over the graphemes of a Line /// An iterator over the graphemes of a Line
pub struct LineGraphemeIter<'a> { pub struct LineGraphemeIter<'a> {
graphemes: RopeGraphemeIter<'a>, graphemes: RopeGraphemeIter<'a>,
grapheme_count: Option<usize>,
ending: LineEnding, ending: LineEnding,
done: bool, done: bool,
} }
@ -443,7 +457,14 @@ impl<'a> Iterator for LineGraphemeIter<'a> {
if self.done { if self.done {
return None; return None;
} }
else if let Some(0) = self.grapheme_count {
return None;
}
else { else {
if let Some(ref mut i) = self.grapheme_count {
*i -= 1;
}
let g = self.graphemes.next(); let g = self.graphemes.next();
if let Some(_) = g { if let Some(_) = g {
return g; return g;

View File

@ -47,7 +47,7 @@ pub trait LineFormatter {
let (line_block, col_i_adjusted) = block_index_and_offset(col_i); let (line_block, col_i_adjusted) = block_index_and_offset(col_i);
// Get an iter into the right block // Get an iter into the right block
let g_iter = line.grapheme_iter_at_index(line_block * LINE_BLOCK_LENGTH); let g_iter = line.grapheme_iter_at_index_with_max_length(line_block * LINE_BLOCK_LENGTH, LINE_BLOCK_LENGTH);
return self.index_to_v2d(g_iter, col_i_adjusted).1; return self.index_to_v2d(g_iter, col_i_adjusted).1;
} }
@ -64,7 +64,7 @@ pub trait LineFormatter {
// Find the right block in the line, and the index within that block // Find the right block in the line, and the index within that block
let (line_block, col_i_adjusted) = block_index_and_offset(col_i); let (line_block, col_i_adjusted) = block_index_and_offset(col_i);
let (mut y, x) = self.index_to_v2d(buf.get_line(line_i).grapheme_iter_at_index(line_block*LINE_BLOCK_LENGTH), col_i_adjusted); let (mut y, x) = self.index_to_v2d(buf.get_line(line_i).grapheme_iter_at_index_with_max_length(line_block*LINE_BLOCK_LENGTH, LINE_BLOCK_LENGTH), col_i_adjusted);
let mut new_y = y as isize + offset; let mut new_y = y as isize + offset;
// First, find the right line while keeping track of the vertical offset // First, find the right line while keeping track of the vertical offset
@ -72,7 +72,7 @@ pub trait LineFormatter {
let mut block_index: usize = line_block; let mut block_index: usize = line_block;
loop { loop {
line = buf.get_line(line_i); line = buf.get_line(line_i);
let (h, _) = self.dimensions(line.grapheme_iter_at_index(line_block*LINE_BLOCK_LENGTH)); let (h, _) = self.dimensions(line.grapheme_iter_at_index_with_max_length(line_block*LINE_BLOCK_LENGTH, LINE_BLOCK_LENGTH));
if new_y >= 0 && new_y < h as isize { if new_y >= 0 && new_y < h as isize {
y = new_y as usize; y = new_y as usize;
@ -110,7 +110,7 @@ pub trait LineFormatter {
else { else {
block_index -= 1; block_index -= 1;
} }
let (h, _) = self.dimensions(line.grapheme_iter_at_index(line_block*LINE_BLOCK_LENGTH)); let (h, _) = self.dimensions(line.grapheme_iter_at_index_with_max_length(line_block*LINE_BLOCK_LENGTH, LINE_BLOCK_LENGTH));
new_y += h as isize; new_y += h as isize;
} }
else { else {
@ -121,7 +121,7 @@ pub trait LineFormatter {
// Next, convert the resulting coordinates back into buffer-wide // Next, convert the resulting coordinates back into buffer-wide
// coordinates. // coordinates.
col_i = (block_index * LINE_BLOCK_LENGTH) + self.v2d_to_index(line.grapheme_iter_at_index(block_index*LINE_BLOCK_LENGTH), (y, x), rounding); col_i = (block_index * LINE_BLOCK_LENGTH) + self.v2d_to_index(line.grapheme_iter_at_index_with_max_length(block_index*LINE_BLOCK_LENGTH, LINE_BLOCK_LENGTH), (y, x), rounding);
return buf.line_col_to_index((line_i, col_i)); return buf.line_col_to_index((line_i, col_i));
} }
@ -136,8 +136,8 @@ pub trait LineFormatter {
let start_index = line_block * LINE_BLOCK_LENGTH; let start_index = line_block * LINE_BLOCK_LENGTH;
// Calculate the horizontal position // Calculate the horizontal position
let (v, _) = self.index_to_v2d(line.grapheme_iter_at_index(start_index), col_i_adjusted); let (v, _) = self.index_to_v2d(line.grapheme_iter_at_index_with_max_length(start_index, LINE_BLOCK_LENGTH), col_i_adjusted);
let mut new_col_i = start_index + self.v2d_to_index(line.grapheme_iter_at_index(start_index), (v, horizontal), (RoundingBehavior::Floor, rounding)); let mut new_col_i = start_index + self.v2d_to_index(line.grapheme_iter_at_index_with_max_length(start_index, LINE_BLOCK_LENGTH), (v, horizontal), (RoundingBehavior::Floor, rounding));
// Make sure we're not pushing the index off the end of the line // Make sure we're not pushing the index off the end of the line
if (line_i + 1) < buf.line_count() if (line_i + 1) < buf.line_count()