feat(prettier) Add IndentIfBreak support (#1420)

This commit is contained in:
Cameron 2023-11-19 03:11:52 +00:00 committed by GitHub
parent cb804d3cd2
commit 08ce4474e1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 1 deletions

View file

@ -15,6 +15,7 @@ pub enum Doc<'a> {
Array(Vec<'a, Doc<'a>>),
/// Increase the level of indentation.
Indent(Vec<'a, Doc<'a>>),
IndentIfBreak(Vec<'a, Doc<'a>>),
/// Mark a group of items which the printer should try to fit on one line.
/// This is the basic command to tell the printer when to break.
/// Groups are usually nested, and the printer will try to fit everything on one line,
@ -117,6 +118,17 @@ fn print_do_to_debug(doc: &Doc<'_>) -> std::string::String {
}
string.push_str("])");
}
Doc::IndentIfBreak(contents) => {
string.push_str("indentIfBreak(");
string.push_str("[\n");
for (idx, doc) in contents.iter().enumerate() {
string.push_str(&print_do_to_debug(doc));
if idx != contents.len() - 1 {
string.push_str(", ");
}
}
string.push_str("]) \n");
}
Doc::Group(contents) => {
string.push_str("group([\n");
for (idx, doc) in contents.iter().enumerate() {

View file

@ -35,6 +35,19 @@ macro_rules! indent {
};
}
#[macro_export]
macro_rules! indent_if_break {
($p:ident, $( $x:expr ),* $(,)?) => {
{
let mut temp_vec = $p.vec();
$(
temp_vec.push($x);
)*
Doc::IndentIfBreak(temp_vec)
}
};
}
#[macro_export]
macro_rules! line {
() => {

View file

@ -52,6 +52,7 @@ impl<'a> Printer<'a> {
Doc::Array(docs) => self.handle_array(indent, mode, docs),
Doc::Indent(docs) => self.handle_indent(indent, mode, docs),
Doc::Group(docs) => self.handle_group(indent, mode, docs),
Doc::IndentIfBreak(docs) => self.handle_indent_if_break(indent, mode, docs),
Doc::Line => self.handle_line(indent, mode),
Doc::Softline => self.handle_softline(indent, mode),
Doc::Hardline => self.handle_hardline(indent),
@ -102,6 +103,26 @@ impl<'a> Printer<'a> {
}
}
fn handle_indent_if_break(
&mut self,
indent: Indent,
mode: Mode,
docs: oxc_allocator::Vec<'a, Doc<'a>>,
) {
match mode {
Mode::Flat => {
self.cmds.extend(
docs.into_iter().rev().map(|doc| Command::new(indent, Mode::Flat, doc)),
);
}
Mode::Break => {
self.cmds.extend(docs.into_iter().rev().map(|doc| {
Command::new(Indent { length: indent.length + 1 }, Mode::Flat, doc)
}));
}
}
}
fn handle_line(&mut self, indent: Indent, mode: Mode) {
if matches!(mode, Mode::Flat) {
self.out.push(b' ');
@ -146,7 +167,10 @@ impl<'a> Printer<'a> {
Doc::Str(string) => {
remaining_width -= string.len() as isize;
}
Doc::Array(docs) | Doc::Indent(docs) | Doc::Group(docs) => {
Doc::IndentIfBreak(docs)
| Doc::Array(docs)
| Doc::Indent(docs)
| Doc::Group(docs) => {
// Prepend docs to the queue
for d in docs.iter().rev() {
queue.push_front(d);