diff --git a/src/utils/lines/spans/chunk.rs b/src/utils/lines/spans/chunk.rs index 838317a..bd87783 100644 --- a/src/utils/lines/spans/chunk.rs +++ b/src/utils/lines/spans/chunk.rs @@ -1,11 +1,22 @@ use super::segment::Segment; /// Non-splittable piece of text. +/// +/// It is made of a list of segments of text. #[derive(Debug, Clone, PartialEq, Eq)] pub struct Chunk { + /// Total width of this chunk. pub width: usize, + + /// This is the segments this chunk contains. pub segments: Vec, + + /// Hard stops are non-optional line breaks (newlines). pub hard_stop: bool, + + /// If a chunk of text ends in a space, it can be compressed a bit. + /// + /// (We can omit the space if it would result in a perfect fit.) pub ends_with_space: bool, } diff --git a/src/utils/lines/spans/lines_iterator.rs b/src/utils/lines/spans/lines_iterator.rs index e14e831..36c9ffc 100644 --- a/src/utils/lines/spans/lines_iterator.rs +++ b/src/utils/lines/spans/lines_iterator.rs @@ -111,16 +111,14 @@ where offset = end; Chunk { width, - segments: vec![ - Segment { - width, - span_id: seg.span_id, - start, - end, - }, - ], + segments: vec![Segment { + width, + span_id: seg.span_id, + start, + end, + }], hard_stop: false, - ends_with_space: false, + ends_with_space: false, // should we? } }) }); @@ -152,7 +150,22 @@ where } } - let width = chunks.iter().map(|c| c.width).sum(); + // We can know text was wrapped if the stop was optional, + // and there's more coming. + let text_wrap = !chunks + .last() + .map(|c| c.hard_stop) + .unwrap_or(true) + && self.iter.peek().is_some(); + + // If we had to break a line in two, then at least pretent we're + // taking the full width. + let width = if text_wrap { + self.width + } else { + chunks.iter().map(|c| c.width).sum() + }; + assert!(width <= self.width); // Concatenate all segments