Beginnings of line wrapping for terminal ui.
This commit is contained in:
parent
413306f814
commit
04816ebe84
|
@ -311,7 +311,7 @@ impl BufferNode {
|
|||
|
||||
// TODO: is this the right thing to do? The idea is that
|
||||
// the non-leaf branch code should put us in the right leaf
|
||||
// anyway, and returning and index equal to the leaf's
|
||||
// anyway, and returning an index equal to the leaf's
|
||||
// grapheme count is putting it on the next line instead of
|
||||
// this one.
|
||||
if r == self.grapheme_count && self.grapheme_count > 0 {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use std::cmp::max;
|
||||
|
||||
use string_utils::{is_line_ending};
|
||||
use buffer::line::{Line, LineGraphemeIter};
|
||||
use buffer::line_formatter::{LineFormatter, RoundingBehavior};
|
||||
|
@ -8,6 +10,7 @@ use buffer::line_formatter::{LineFormatter, RoundingBehavior};
|
|||
|
||||
pub struct ConsoleLineFormatter {
|
||||
pub tab_width: u8,
|
||||
pub wrap_width: usize,
|
||||
}
|
||||
|
||||
|
||||
|
@ -15,6 +18,7 @@ impl ConsoleLineFormatter {
|
|||
pub fn new(tab_width: u8) -> ConsoleLineFormatter {
|
||||
ConsoleLineFormatter {
|
||||
tab_width: tab_width,
|
||||
wrap_width: 40,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,52 +52,48 @@ impl<'a> LineFormatter for ConsoleLineFormatter {
|
|||
}
|
||||
|
||||
fn dimensions(&self, line: &Line) -> (usize, usize) {
|
||||
return (1, self.vis_width(line));
|
||||
let mut dim: (usize, usize) = (0, 0);
|
||||
|
||||
for (_, pos, width) in self.vis_grapheme_iter(line) {
|
||||
dim = (max(dim.0, pos.0), max(dim.1, pos.1 + width));
|
||||
}
|
||||
|
||||
dim.0 += 1;
|
||||
|
||||
return dim;
|
||||
}
|
||||
|
||||
|
||||
fn index_to_v2d(&self, line: &Line, index: usize) -> (usize, usize) {
|
||||
let mut pos = 0;
|
||||
let mut iter = line.grapheme_iter();
|
||||
let mut pos = (0, 0);
|
||||
let mut iter = self.vis_grapheme_iter(line);
|
||||
|
||||
for _ in range(0, index) {
|
||||
if let Some(g) = iter.next() {
|
||||
let w = grapheme_vis_width_at_vis_pos(g, pos, self.tab_width as usize);
|
||||
pos += w;
|
||||
if let Some((_, _pos, _)) = iter.next() {
|
||||
pos = _pos;
|
||||
}
|
||||
else {
|
||||
panic!("ConsoleLineFormatter::index_to_v2d(): index past end of line.");
|
||||
}
|
||||
}
|
||||
|
||||
return (0, pos);
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
fn v2d_to_index(&self, line: &Line, v2d: (usize, usize), rounding: (RoundingBehavior, RoundingBehavior)) -> usize {
|
||||
let mut pos = 0;
|
||||
// TODO: handle rounding modes
|
||||
let mut i = 0;
|
||||
let mut iter = line.grapheme_iter();
|
||||
|
||||
while pos < v2d.1 {
|
||||
if let Some(g) = iter.next() {
|
||||
let w = grapheme_vis_width_at_vis_pos(g, pos, self.tab_width as usize);
|
||||
if (w + pos) > v2d.1 {
|
||||
let d1 = v2d.1 - pos;
|
||||
let d2 = (pos + w) - v2d.1;
|
||||
if d2 < d1 {
|
||||
i += 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else {
|
||||
pos += w;
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (_, pos, width) in self.vis_grapheme_iter(line) {
|
||||
if pos.0 > v2d.0 {
|
||||
break;
|
||||
}
|
||||
else if pos.0 == v2d.0 && pos.1 > v2d.1 {
|
||||
break;
|
||||
}
|
||||
|
||||
i += 1;
|
||||
}
|
||||
|
||||
return i;
|
||||
|
@ -118,12 +118,18 @@ impl<'a> Iterator for ConsoleLineFormatterVisIter<'a> {
|
|||
|
||||
fn next(&mut self) -> Option<(&'a str, (usize, usize), usize)> {
|
||||
if let Some(g) = self.grapheme_iter.next() {
|
||||
let pos = self.pos;
|
||||
|
||||
let width = grapheme_vis_width_at_vis_pos(g, self.pos.1, self.f.tab_width as usize);
|
||||
self.pos = (self.pos.0, self.pos.1 + width);
|
||||
|
||||
return Some((g, (pos.0, pos.1), width));
|
||||
if (self.pos.1 + width) > self.f.wrap_width {
|
||||
let pos = (self.pos.0 + 1, 0);
|
||||
self.pos = (self.pos.0 + 1, width);
|
||||
return Some((g, pos, width));
|
||||
}
|
||||
else {
|
||||
let pos = self.pos;
|
||||
self.pos = (self.pos.0, self.pos.1 + width);
|
||||
return Some((g, pos, width));
|
||||
}
|
||||
}
|
||||
else {
|
||||
return None;
|
||||
|
|
Loading…
Reference in New Issue
Block a user