Move show_spaces option to spans::LinesIterator

This commit is contained in:
Alexandre Bury 2018-02-16 17:10:29 -08:00
parent 2760e92ce6
commit d0a186d01e
2 changed files with 54 additions and 41 deletions

View File

@ -1,6 +1,4 @@
use super::{prefix, Row}; use super::Row;
use unicode_segmentation::UnicodeSegmentation;
use unicode_width::UnicodeWidthStr;
use utils::lines::spans; use utils::lines::spans;
use utils::span::{IndexedSpan, SpannedText}; use utils::span::{IndexedSpan, SpannedText};
@ -13,10 +11,6 @@ pub struct LinesIterator<'a> {
/// Available width. Don't output lines wider than that. /// Available width. Don't output lines wider than that.
width: usize, width: usize,
/// If `true`, keep a blank cell at the end of lines
/// when a whitespace or newline should be.
show_spaces: bool,
} }
struct DummySpannedText<'a> { struct DummySpannedText<'a> {
@ -50,21 +44,17 @@ impl<'a> LinesIterator<'a> {
pub fn new(content: &'a str, width: usize) -> Self { pub fn new(content: &'a str, width: usize) -> Self {
let iter = let iter =
spans::LinesIterator::new(DummySpannedText::new(content), width); spans::LinesIterator::new(DummySpannedText::new(content), width);
let show_spaces = false; LinesIterator { iter, width }
LinesIterator {
iter,
width,
show_spaces,
}
} }
/// Leave a blank cell at the end of lines. /// Leave a blank cell at the end of lines.
/// ///
/// Unless a word had to be truncated, in which case /// Unless a word had to be truncated, in which case
/// it takes the entire width. /// it takes the entire width.
pub fn show_spaces(mut self) -> Self { pub fn show_spaces(self) -> Self {
self.show_spaces = true; let iter = self.iter.show_spaces();
self let width = self.width;
LinesIterator { iter, width }
} }
} }

View File

@ -2,7 +2,7 @@ use super::chunk::{Chunk, ChunkPart};
use super::chunk_iterator::ChunkIterator; use super::chunk_iterator::ChunkIterator;
use super::prefix::prefix; use super::prefix::prefix;
use super::row::Row; use super::row::Row;
use super::segment::{Segment}; use super::segment::Segment;
use super::segment_merge_iterator::SegmentMergeIterator; use super::segment_merge_iterator::SegmentMergeIterator;
use std::iter::Peekable; use std::iter::Peekable;
use std::rc::Rc; use std::rc::Rc;
@ -26,6 +26,10 @@ where
/// If a chunk wouldn't fit, we had to cut it in pieces. /// If a chunk wouldn't fit, we had to cut it in pieces.
/// This is how far in the current chunk we are. /// This is how far in the current chunk we are.
chunk_offset: ChunkPart, chunk_offset: ChunkPart,
/// If `true`, keep a blank cell at the end of lines
/// when a whitespace or newline should be.
show_spaces: bool,
} }
impl<S> LinesIterator<S> impl<S> LinesIterator<S>
@ -41,8 +45,18 @@ where
source, source,
width, width,
chunk_offset: ChunkPart::default(), chunk_offset: ChunkPart::default(),
show_spaces: false,
} }
} }
/// Leave a blank cell at the end of lines.
///
/// Unless a word had to be truncated, in which case
/// it can take the entire width.
pub fn show_spaces(mut self) -> Self {
self.show_spaces = true;
self
}
} }
impl<S> Iterator for LinesIterator<S> impl<S> Iterator for LinesIterator<S>
@ -53,9 +67,17 @@ where
fn next(&mut self) -> Option<Row> { fn next(&mut self) -> Option<Row> {
// Let's build a beautiful row. // Let's build a beautiful row.
let allowed_width = if self.show_spaces {
// Remove 1 from the available space, if possible.
// But only for regular words.
// If we have to split a chunk, forget about that.
self.width.saturating_sub(1)
} else {
self.width
};
let mut chunks = let mut chunks =
prefix(&mut self.iter, self.width, &mut self.chunk_offset); prefix(&mut self.iter, allowed_width, &mut self.chunk_offset);
if chunks.is_empty() { if chunks.is_empty() {
// Desperate action to make something fit: // Desperate action to make something fit:
@ -71,7 +93,8 @@ where
// Try to fit part of it? // Try to fit part of it?
let source = self.source.as_ref(); let source = self.source.as_ref();
let graphemes = chunk.segments.iter().flat_map(move |seg| { let graphemes =
chunk.segments.iter().flat_map(move |seg| {
let mut offset = seg.start; let mut offset = seg.start;
let text = seg.resolve_plain(source); let text = seg.resolve_plain(source);