use unicode_width::UnicodeWidthStr;
use super::{
ParagraphWriter,
PrefixLine,
continuation_folds_tail,
continuation_prefix_for,
hard_break::trailing_hard_break_marker_len,
wrap_preserving_code,
wraps_to_tail,
};
impl ParagraphWriter<'_> {
pub(super) fn append_stable_pending_prefix(&mut self, line: &PrefixLine<'_>, available: usize) {
if line.repeat_prefix {
self.append_wrapped_with_prefix_width(line, available);
return;
}
let mut lines = wrap_preserving_code(line.rest, available).into_iter();
let Some(first_line) = lines.next() else {
self.out.push(line.prefix.to_string());
return;
};
self.out.push(format!("{}{first_line}", line.prefix));
let continuation_prefix =
continuation_prefix_for(line.prefix.as_ref(), false, line.outer_prefix.as_deref());
let mut tail_segment = String::new();
for wrapped_line in lines {
let marker_len = trailing_hard_break_marker_len(&wrapped_line);
let content_end = wrapped_line.len() - marker_len;
let marker = &wrapped_line[content_end..];
if !tail_segment.is_empty() {
tail_segment.push(' ');
}
tail_segment.push_str(&wrapped_line[..content_end]);
if marker_len > 0 {
let (measured, appended) = if marker.trim().is_empty() {
("", marker)
} else {
(marker, "")
};
tail_segment.push_str(measured);
self.emit_tail_segment(
&mut tail_segment,
appended,
continuation_prefix.as_str(),
available,
);
}
}
self.emit_tail_segment(&mut tail_segment, "", &continuation_prefix, available);
}
fn emit_tail_segment(
&mut self,
tail_segment: &mut String,
marker: &str,
continuation_prefix: &str,
available: usize,
) {
self.out.extend(
wrap_preserving_code(tail_segment, available)
.into_iter()
.map(|tail_line| format!("{continuation_prefix}{tail_line}")),
);
if let Some(last_line) = self.out.last_mut() {
last_line.push_str(marker);
}
tail_segment.clear();
}
pub(in crate::wrap) fn ensure_trailing_hard_break_on_last_line(&mut self) {
if let Some(last) = self.out.last_mut()
&& trailing_hard_break_marker_len(last) == 0
{
last.push_str(" ");
}
}
pub(super) fn prefix_line_needs_tail_deferral(&self, line: &PrefixLine<'_>) -> bool {
let continuation_prefix = continuation_prefix_for(
line.prefix.as_ref(),
line.repeat_prefix,
line.outer_prefix.as_deref(),
);
if !continuation_folds_tail(continuation_prefix.as_str()) {
return false;
}
let prefix_width = UnicodeWidthStr::width(line.prefix.as_ref());
let available = self.width.saturating_sub(prefix_width).max(1);
wraps_to_tail(line.rest, available)
}
}