Implemented word wrapping.
This commit is contained in:
parent
e1e06633c7
commit
cbff82b462
|
@ -24,7 +24,7 @@ impl ConsoleLineFormatter {
|
||||||
pub fn new(tab_width: u8) -> ConsoleLineFormatter {
|
pub fn new(tab_width: u8) -> ConsoleLineFormatter {
|
||||||
ConsoleLineFormatter {
|
ConsoleLineFormatter {
|
||||||
tab_width: tab_width,
|
tab_width: tab_width,
|
||||||
wrap_type: WrapType::CharWrap(40),
|
wrap_type: WrapType::WordWrap(40),
|
||||||
maintain_indent: true,
|
maintain_indent: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,8 @@ impl ConsoleLineFormatter {
|
||||||
pos: (0, 0),
|
pos: (0, 0),
|
||||||
indent: 0,
|
indent: 0,
|
||||||
indent_found: false,
|
indent_found: false,
|
||||||
|
word_buf: Vec::new(),
|
||||||
|
word_i: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -133,8 +135,62 @@ where T: Iterator<Item=&'a str>
|
||||||
grapheme_iter: T,
|
grapheme_iter: T,
|
||||||
f: &'a ConsoleLineFormatter,
|
f: &'a ConsoleLineFormatter,
|
||||||
pos: (usize, usize),
|
pos: (usize, usize),
|
||||||
|
|
||||||
indent: usize,
|
indent: usize,
|
||||||
indent_found: bool,
|
indent_found: bool,
|
||||||
|
|
||||||
|
word_buf: Vec<&'a str>,
|
||||||
|
word_i: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl<'a, T> ConsoleLineFormatterVisIter<'a, T>
|
||||||
|
where T: Iterator<Item=&'a str>
|
||||||
|
{
|
||||||
|
fn next_nowrap(&mut self, g: &'a str) -> Option<(&'a str, (usize, usize), usize)> {
|
||||||
|
let width = grapheme_vis_width_at_vis_pos(g, self.pos.1, self.f.tab_width as usize);
|
||||||
|
|
||||||
|
let pos = self.pos;
|
||||||
|
self.pos = (self.pos.0, self.pos.1 + width);
|
||||||
|
return Some((g, pos, width));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn next_charwrap(&mut self, g: &'a str, wrap_width: usize) -> Option<(&'a str, (usize, usize), usize)> {
|
||||||
|
let width = grapheme_vis_width_at_vis_pos(g, self.pos.1, self.f.tab_width as usize);
|
||||||
|
|
||||||
|
if (self.pos.1 + width) > wrap_width {
|
||||||
|
if !self.indent_found {
|
||||||
|
self.indent = 0;
|
||||||
|
self.indent_found = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.f.maintain_indent {
|
||||||
|
let pos = (self.pos.0 + self.f.single_line_height(), self.indent);
|
||||||
|
self.pos = (self.pos.0 + self.f.single_line_height(), self.indent + width);
|
||||||
|
return Some((g, pos, width));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let pos = (self.pos.0 + self.f.single_line_height(), 0);
|
||||||
|
self.pos = (self.pos.0 + self.f.single_line_height(), width);
|
||||||
|
return Some((g, pos, width));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if !self.indent_found {
|
||||||
|
if is_whitespace(g) {
|
||||||
|
self.indent += width;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
self.indent_found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let pos = self.pos;
|
||||||
|
self.pos = (self.pos.0, self.pos.1 + width);
|
||||||
|
return Some((g, pos, width));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -148,11 +204,7 @@ where T: Iterator<Item=&'a str>
|
||||||
match self.f.wrap_type {
|
match self.f.wrap_type {
|
||||||
WrapType::NoWrap => {
|
WrapType::NoWrap => {
|
||||||
if let Some(g) = self.grapheme_iter.next() {
|
if let Some(g) = self.grapheme_iter.next() {
|
||||||
let width = grapheme_vis_width_at_vis_pos(g, self.pos.1, self.f.tab_width as usize);
|
return self.next_nowrap(g);
|
||||||
|
|
||||||
let pos = self.pos;
|
|
||||||
self.pos = (self.pos.0, self.pos.1 + width);
|
|
||||||
return Some((g, pos, width));
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return None;
|
return None;
|
||||||
|
@ -160,51 +212,58 @@ where T: Iterator<Item=&'a str>
|
||||||
},
|
},
|
||||||
|
|
||||||
WrapType::CharWrap(wrap_width) => {
|
WrapType::CharWrap(wrap_width) => {
|
||||||
if let Some(g) = self.grapheme_iter.next() {
|
if let Some(g) = self.grapheme_iter.next() {
|
||||||
let width = grapheme_vis_width_at_vis_pos(g, self.pos.1, self.f.tab_width as usize);
|
return self.next_charwrap(g, wrap_width);
|
||||||
|
|
||||||
if (self.pos.1 + width) > wrap_width {
|
|
||||||
if !self.indent_found {
|
|
||||||
self.indent = 0;
|
|
||||||
self.indent_found = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.f.maintain_indent {
|
|
||||||
let pos = (self.pos.0 + self.f.single_line_height(), self.indent);
|
|
||||||
self.pos = (self.pos.0 + self.f.single_line_height(), self.indent + width);
|
|
||||||
return Some((g, pos, width));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
let pos = (self.pos.0 + self.f.single_line_height(), 0);
|
|
||||||
self.pos = (self.pos.0 + self.f.single_line_height(), width);
|
|
||||||
return Some((g, pos, width));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if !self.indent_found {
|
|
||||||
if is_whitespace(g) {
|
|
||||||
self.indent += width;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
self.indent_found = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let pos = self.pos;
|
|
||||||
self.pos = (self.pos.0, self.pos.1 + width);
|
|
||||||
return Some((g, pos, width));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
WrapType::WordWrap(_) => {
|
WrapType::WordWrap(wrap_width) => {
|
||||||
// TODO
|
// Get next word if necessary
|
||||||
return None;
|
if self.word_i >= self.word_buf.len() {
|
||||||
|
let mut word_width = 0;
|
||||||
|
self.word_buf.truncate(0);
|
||||||
|
while let Some(g) = self.grapheme_iter.next() {
|
||||||
|
self.word_buf.push(g);
|
||||||
|
let width = grapheme_vis_width_at_vis_pos(g, self.pos.1 + word_width, self.f.tab_width as usize);
|
||||||
|
word_width += width;
|
||||||
|
if is_whitespace(g) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.word_buf.len() == 0 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
else if !self.indent_found && !is_whitespace(self.word_buf[0]) {
|
||||||
|
self.indent_found = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move to next line if necessary
|
||||||
|
if (self.pos.1 + word_width) > wrap_width {
|
||||||
|
if !self.indent_found {
|
||||||
|
self.indent = 0;
|
||||||
|
self.indent_found = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.f.maintain_indent {
|
||||||
|
self.pos = (self.pos.0 + self.f.single_line_height(), self.indent);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
self.pos = (self.pos.0 + self.f.single_line_height(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.word_i = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate over the word
|
||||||
|
let g = self.word_buf[self.word_i];
|
||||||
|
self.word_i += 1;
|
||||||
|
return self.next_charwrap(g, wrap_width);
|
||||||
},
|
},
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user