diff --git a/crates/ruff_formatter/src/lib.rs b/crates/ruff_formatter/src/lib.rs index 7e5f047afffffb..3ef9b94e61de2b 100644 --- a/crates/ruff_formatter/src/lib.rs +++ b/crates/ruff_formatter/src/lib.rs @@ -429,7 +429,6 @@ pub type FormatResult = Result; /// impl Format for Paragraph { /// fn fmt(&self, f: &mut Formatter) -> FormatResult<()> { /// write!(f, [ -/// hard_line_break(), /// text(&self.0, None), /// hard_line_break(), /// ]) @@ -440,7 +439,7 @@ pub type FormatResult = Result; /// let paragraph = Paragraph(String::from("test")); /// let formatted = format!(SimpleFormatContext::default(), [paragraph])?; /// -/// assert_eq!("\ntest\n", formatted.print()?.as_code()); +/// assert_eq!("test\n", formatted.print()?.as_code()); /// # Ok(()) /// # } /// ``` diff --git a/crates/ruff_formatter/src/printer/mod.rs b/crates/ruff_formatter/src/printer/mod.rs index b081dfe9ecfdff..3d8d58be62ce91 100644 --- a/crates/ruff_formatter/src/printer/mod.rs +++ b/crates/ruff_formatter/src/printer/mod.rs @@ -124,7 +124,7 @@ impl<'a> Printer<'a> { self.flush_line_suffixes(queue, stack, Some(element)); } else { // Only print a newline if the current line isn't already empty - if self.state.line_width > 0 || self.state.buffer.is_empty() { + if self.state.line_width > 0 { self.print_char('\n'); } diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/empty_multiple_trailing_newlines.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/empty_multiple_trailing_newlines.py new file mode 100644 index 00000000000000..b28b04f643122b --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/empty_multiple_trailing_newlines.py @@ -0,0 +1,3 @@ + + + diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/empty_now_newline.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/empty_now_newline.py new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/empty_trailing_newline.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/empty_trailing_newline.py new file mode 100644 index 00000000000000..8b137891791fe9 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/empty_trailing_newline.py @@ -0,0 +1 @@ + diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/empty_whitespace.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/empty_whitespace.py new file mode 100644 index 00000000000000..991aa1a51e709a --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/empty_whitespace.py @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/crates/ruff_python_formatter/src/module/mod_module.rs b/crates/ruff_python_formatter/src/module/mod_module.rs index 44337350e57bae..304c885d41f014 100644 --- a/crates/ruff_python_formatter/src/module/mod_module.rs +++ b/crates/ruff_python_formatter/src/module/mod_module.rs @@ -1,5 +1,6 @@ use ruff_formatter::write; use ruff_python_ast::ModModule; +use ruff_python_trivia::lines_after; use crate::comments::SourceComment; use crate::prelude::*; @@ -11,16 +12,27 @@ pub struct FormatModModule; impl FormatNodeRule for FormatModModule { fn fmt_fields(&self, item: &ModModule, f: &mut PyFormatter) -> FormatResult<()> { - let ModModule { range: _, body } = item; + let ModModule { range, body } = item; - write!( - f, - [ - body.format().with_options(SuiteKind::TopLevel), - // Trailing newline at the end of the file - hard_line_break() - ] - ) + if body.is_empty() { + // Only preserve an empty line if the source contains an empty line too. + if !f.context().comments().has_leading(item) + && lines_after(range.end(), f.context().source()) != 0 + { + empty_line().fmt(f) + } else { + Ok(()) + } + } else { + write!( + f, + [ + body.format().with_options(SuiteKind::TopLevel), + // Trailing newline at the end of the file + hard_line_break() + ] + ) + } } fn fmt_dangling_comments( diff --git a/crates/ruff_python_formatter/tests/snapshots/format@empty_multiple_trailing_newlines.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@empty_multiple_trailing_newlines.py.snap new file mode 100644 index 00000000000000..acae2f4cc3f528 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/format@empty_multiple_trailing_newlines.py.snap @@ -0,0 +1,18 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/empty_multiple_trailing_newlines.py +--- +## Input +```py + + + +``` + +## Output +```py + +``` + + + diff --git a/crates/ruff_python_formatter/tests/snapshots/format@empty_now_newline.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@empty_now_newline.py.snap new file mode 100644 index 00000000000000..77fbee7d919c72 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/format@empty_now_newline.py.snap @@ -0,0 +1,14 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/empty_now_newline.py +--- +## Input +```py +``` + +## Output +```py +``` + + + diff --git a/crates/ruff_python_formatter/tests/snapshots/format@empty_trailing_newline.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@empty_trailing_newline.py.snap new file mode 100644 index 00000000000000..a89a4db2c6866e --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/format@empty_trailing_newline.py.snap @@ -0,0 +1,16 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/empty_trailing_newline.py +--- +## Input +```py + +``` + +## Output +```py + +``` + + + diff --git a/crates/ruff_python_formatter/tests/snapshots/format@empty_whitespace.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@empty_whitespace.py.snap new file mode 100644 index 00000000000000..33604dc12f6216 --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/format@empty_whitespace.py.snap @@ -0,0 +1,14 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/empty_whitespace.py +--- +## Input +```py + ``` + +## Output +```py +``` + + + diff --git a/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__indent.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__indent.py.snap index 3a3392f35e0258..5330ab331ef674 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__indent.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@fmt_on_off__indent.py.snap @@ -17,7 +17,6 @@ magic-trailing-comma = Respect ``` ```py - ``` @@ -31,7 +30,6 @@ magic-trailing-comma = Respect ``` ```py - ``` @@ -45,7 +43,6 @@ magic-trailing-comma = Respect ``` ```py - ```