diff --git a/crates/rome_formatter/src/format_element.rs b/crates/rome_formatter/src/format_element.rs index 5f89fad935a..a4b26939326 100644 --- a/crates/rome_formatter/src/format_element.rs +++ b/crates/rome_formatter/src/format_element.rs @@ -735,6 +735,41 @@ pub fn group_elements_with_options( format_elements![leading, group, trailing] } +/// IR element that forces the parent group to print in expanded mode. +/// +/// Has no effect if used outside of a group or element that introduce implicit groups (fill element). +/// +/// ## Examples +/// +/// ``` +/// use rome_formatter::{Formatted, LineWidth}; +/// use rome_formatter::prelude::*; +/// +/// let elements = group_elements(format_elements![ +/// token("["), +/// soft_block_indent(format_elements![ +/// token("'Good morning! How are you today?',"), +/// soft_line_break_or_space(), +/// token("2,"), +/// expand_parent(), // Forces the parent to expand +/// soft_line_break_or_space(), +/// token("3"), +/// ]), +/// token("]"), +/// ]); +/// +/// assert_eq!( +/// "[\n\t'Good morning! How are you today?',\n\t2,\n\t3\n]", +/// Formatted::new(elements, PrinterOptions::default()).print().as_code() +/// ); +/// ``` +/// +/// ## Prettier +/// Equivalent to Prettier's `break_parent` IR element +pub const fn expand_parent() -> FormatElement { + FormatElement::ExpandParent +} + /// Creates a group that forces all elements inside it to be printed on a /// single line. This behavior can in turn be escaped by introducing an inner /// `Group` element that will resume the normal breaking behavior of the printer. @@ -1083,6 +1118,9 @@ pub enum FormatElement { /// See [crate::group_elements] for documentation and examples. Group(Group), + /// Forces the parent group to print in expanded mode. + ExpandParent, + /// See [crate::hard_group_elements] for documentation and examples. HardGroup(Group), @@ -1196,6 +1234,7 @@ impl Debug for FormatElement { .debug_tuple("Verbatim") .field(&verbatim.element) .finish(), + FormatElement::ExpandParent => write!(fmt, "ExpandParent"), } } } @@ -1585,6 +1624,7 @@ impl FormatElement { FormatElement::Comment(content) => content.will_break(), FormatElement::Verbatim(verbatim) => verbatim.element.will_break(), FormatElement::LineSuffixBoundary => false, + FormatElement::ExpandParent => true, } } diff --git a/crates/rome_formatter/src/printer/mod.rs b/crates/rome_formatter/src/printer/mod.rs index 6ecf433dbac..e1b3246458b 100644 --- a/crates/rome_formatter/src/printer/mod.rs +++ b/crates/rome_formatter/src/printer/mod.rs @@ -223,8 +223,7 @@ impl<'a> Printer<'a> { } FormatElement::LineSuffixBoundary => { const HARD_BREAK: &FormatElement = &hard_line_break(); - // enqueue a line break, this will flush the line suffix - queue.enqueue(PrintElementCall::new(HARD_BREAK, args)); + self.queue_line_suffixes(HARD_BREAK, args, queue); } FormatElement::Comment(content) => { @@ -241,6 +240,9 @@ impl<'a> Printer<'a> { queue.enqueue(PrintElementCall::new(&verbatim.element, args)); } + FormatElement::ExpandParent => { + // No-op, only has an effect on `fits` + } } } @@ -603,7 +605,7 @@ fn fits_on_line<'a>( pending_indent: printer.state.pending_indent, pending_space: printer.state.pending_space, line_width: printer.state.line_width, - has_line_suffix: printer.state.line_suffixes.is_empty(), + has_line_suffix: printer.state.line_suffixes.len() > 0, }; let result = loop { @@ -765,6 +767,11 @@ fn fits_element_on_line<'a, 'rest>( FormatElement::Verbatim(verbatim) => { queue.enqueue(PrintElementCall::new(&verbatim.element, args)) } + FormatElement::ExpandParent => { + if args.mode.is_flat() || args.hard_group { + return Fits::No; + } + } } Fits::Maybe diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/comments/while.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/comments/while.js.snap index f53d646b959..8f405798899 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/js/comments/while.js.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/js/comments/while.js.snap @@ -1,6 +1,8 @@ --- source: crates/rome_js_formatter/tests/prettier_tests.rs +assertion_line: 121 expression: while.js + --- # Input ```js