mirror of https://github.com/zkat/miette.git
Add `wrap_lines: bool` option allowing wrapping be disabled entirely
This commit is contained in:
parent
7ff4f874d6
commit
1168d645ca
|
|
@ -56,6 +56,7 @@ pub struct MietteHandlerOpts {
|
|||
pub(crate) tab_width: Option<usize>,
|
||||
pub(crate) with_cause_chain: Option<bool>,
|
||||
pub(crate) break_words: Option<bool>,
|
||||
pub(crate) wrap_lines: Option<bool>,
|
||||
pub(crate) word_separator: Option<textwrap::WordSeparator>,
|
||||
pub(crate) word_splitter: Option<textwrap::WordSplitter>,
|
||||
}
|
||||
|
|
@ -89,6 +90,16 @@ impl MietteHandlerOpts {
|
|||
self
|
||||
}
|
||||
|
||||
/// If true, long lines can be wrapped.
|
||||
///
|
||||
/// If false, long lines will not be broken when they exceed the width.
|
||||
///
|
||||
/// Defaults to true.
|
||||
pub fn wrap_lines(mut self, wrap_lines: bool) -> Self {
|
||||
self.wrap_lines = Some(wrap_lines);
|
||||
self
|
||||
}
|
||||
|
||||
/// If true, long words can be broken when wrapping.
|
||||
///
|
||||
/// If false, long words will not be broken when they exceed the width.
|
||||
|
|
@ -98,7 +109,6 @@ impl MietteHandlerOpts {
|
|||
self.break_words = Some(break_words);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the `textwrap::WordSeparator` to use when determining wrap points.
|
||||
pub fn word_separator(mut self, word_separator: textwrap::WordSeparator) -> Self {
|
||||
self.word_separator = Some(word_separator);
|
||||
|
|
@ -260,6 +270,9 @@ impl MietteHandlerOpts {
|
|||
if let Some(b) = self.break_words {
|
||||
handler = handler.with_break_words(b)
|
||||
}
|
||||
if let Some(b) = self.wrap_lines {
|
||||
handler = handler.with_wrap_lines(b)
|
||||
}
|
||||
if let Some(s) = self.word_separator {
|
||||
handler = handler.with_word_separator(s)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ pub struct GraphicalReportHandler {
|
|||
pub(crate) context_lines: usize,
|
||||
pub(crate) tab_width: usize,
|
||||
pub(crate) with_cause_chain: bool,
|
||||
pub(crate) wrap_lines: bool,
|
||||
pub(crate) break_words: bool,
|
||||
pub(crate) word_separator: Option<textwrap::WordSeparator>,
|
||||
pub(crate) word_splitter: Option<textwrap::WordSplitter>,
|
||||
|
|
@ -54,6 +55,7 @@ impl GraphicalReportHandler {
|
|||
context_lines: 1,
|
||||
tab_width: 4,
|
||||
with_cause_chain: true,
|
||||
wrap_lines: true,
|
||||
break_words: true,
|
||||
word_separator: None,
|
||||
word_splitter: None,
|
||||
|
|
@ -69,6 +71,7 @@ impl GraphicalReportHandler {
|
|||
footer: None,
|
||||
context_lines: 1,
|
||||
tab_width: 4,
|
||||
wrap_lines: true,
|
||||
with_cause_chain: true,
|
||||
break_words: true,
|
||||
word_separator: None,
|
||||
|
|
@ -131,6 +134,12 @@ impl GraphicalReportHandler {
|
|||
self
|
||||
}
|
||||
|
||||
/// Enables or disables wrapping of lines to fit the width.
|
||||
pub fn with_wrap_lines(mut self, wrap_lines: bool) -> Self {
|
||||
self.wrap_lines = wrap_lines;
|
||||
self
|
||||
}
|
||||
|
||||
/// Enables or disables breaking of words during wrapping.
|
||||
pub fn with_break_words(mut self, break_words: bool) -> Self {
|
||||
self.break_words = break_words;
|
||||
|
|
@ -197,7 +206,7 @@ impl GraphicalReportHandler {
|
|||
opts = opts.word_splitter(word_splitter);
|
||||
}
|
||||
|
||||
writeln!(f, "{}", textwrap::fill(footer, opts))?;
|
||||
writeln!(f, "{}", self.wrap(footer, opts))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -258,7 +267,7 @@ impl GraphicalReportHandler {
|
|||
opts = opts.word_splitter(word_splitter);
|
||||
}
|
||||
|
||||
writeln!(f, "{}", textwrap::fill(&diagnostic.to_string(), opts))?;
|
||||
writeln!(f, "{}", self.wrap(&diagnostic.to_string(), opts))?;
|
||||
|
||||
if !self.with_cause_chain {
|
||||
return Ok(());
|
||||
|
|
@ -314,10 +323,10 @@ impl GraphicalReportHandler {
|
|||
inner_renderer.with_cause_chain = false;
|
||||
inner_renderer.render_report(&mut inner, diag)?;
|
||||
|
||||
writeln!(f, "{}", textwrap::fill(&inner, opts))?;
|
||||
writeln!(f, "{}", self.wrap(&inner, opts))?;
|
||||
}
|
||||
ErrorKind::StdError(err) => {
|
||||
writeln!(f, "{}", textwrap::fill(&err.to_string(), opts))?;
|
||||
writeln!(f, "{}", self.wrap(&err.to_string(), opts))?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -341,7 +350,7 @@ impl GraphicalReportHandler {
|
|||
opts = opts.word_splitter(word_splitter);
|
||||
}
|
||||
|
||||
writeln!(f, "{}", textwrap::fill(&help.to_string(), opts))?;
|
||||
writeln!(f, "{}", self.wrap(&help.to_string(), opts))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -810,6 +819,41 @@ impl GraphicalReportHandler {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn wrap(&self, text: &str, opts: textwrap::Options<'_>) -> String {
|
||||
if self.wrap_lines {
|
||||
textwrap::fill(text, opts)
|
||||
} else {
|
||||
// Format without wrapping, but retain the indentation options
|
||||
// Implementation based on `textwrap::indent`
|
||||
let mut result = String::with_capacity(2 * text.len());
|
||||
let trimmed_indent = opts.subsequent_indent.trim_end();
|
||||
for (idx, line) in text.split_terminator('\n').enumerate() {
|
||||
if idx > 0 {
|
||||
result.push('\n');
|
||||
}
|
||||
if idx == 0 {
|
||||
if line.trim().is_empty() {
|
||||
result.push_str(opts.initial_indent.trim_end());
|
||||
} else {
|
||||
result.push_str(opts.initial_indent);
|
||||
}
|
||||
} else {
|
||||
if line.trim().is_empty() {
|
||||
result.push_str(trimmed_indent);
|
||||
} else {
|
||||
result.push_str(opts.subsequent_indent);
|
||||
}
|
||||
}
|
||||
result.push_str(line);
|
||||
}
|
||||
if text.ends_with('\n') {
|
||||
// split_terminator will have eaten the final '\n'.
|
||||
result.push('\n');
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
fn write_linum(&self, f: &mut impl fmt::Write, width: usize, linum: usize) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
|
|
|
|||
|
|
@ -218,6 +218,50 @@ fn word_wrap_options() -> Result<(), MietteError> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn wrap_option() -> Result<(), MietteError> {
|
||||
// A line should break on the width
|
||||
let out = fmt_report_with_settings(
|
||||
Report::msg("abc def ghi jkl mno pqr stu vwx yz abc def ghi jkl mno pqr stu vwx yz"),
|
||||
|handler| handler.with_width(15),
|
||||
);
|
||||
let expected = r#" × abc def
|
||||
│ ghi jkl
|
||||
│ mno pqr
|
||||
│ stu vwx
|
||||
│ yz abc
|
||||
│ def ghi
|
||||
│ jkl mno
|
||||
│ pqr stu
|
||||
│ vwx yz
|
||||
"#
|
||||
.to_string();
|
||||
assert_eq!(expected, out);
|
||||
|
||||
// Unless, wrapping is disabled
|
||||
let out = fmt_report_with_settings(
|
||||
Report::msg("abc def ghi jkl mno pqr stu vwx yz abc def ghi jkl mno pqr stu vwx yz"),
|
||||
|handler| handler.with_width(15).with_wrap_lines(false),
|
||||
);
|
||||
let expected =
|
||||
" × abc def ghi jkl mno pqr stu vwx yz abc def ghi jkl mno pqr stu vwx yz\n".to_string();
|
||||
assert_eq!(expected, out);
|
||||
|
||||
// Then, user-defined new lines should be preserved wrapping is disabled
|
||||
let out = fmt_report_with_settings(
|
||||
Report::msg("abc def ghi jkl mno pqr stu vwx yz\nabc def ghi jkl mno pqr stu vwx yz\nabc def ghi jkl mno pqr stu vwx yz"),
|
||||
|handler| handler.with_width(15).with_wrap_lines(false),
|
||||
);
|
||||
let expected = r#" × abc def ghi jkl mno pqr stu vwx yz
|
||||
│ abc def ghi jkl mno pqr stu vwx yz
|
||||
│ abc def ghi jkl mno pqr stu vwx yz
|
||||
"#
|
||||
.to_string();
|
||||
assert_eq!(expected, out);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_source() -> Result<(), MietteError> {
|
||||
#[derive(Debug, Diagnostic, Error)]
|
||||
|
|
|
|||
Loading…
Reference in New Issue