diff --git a/src/formatter.rs b/src/formatter.rs index 12f00a0..c255a57 100644 --- a/src/formatter.rs +++ b/src/formatter.rs @@ -332,12 +332,30 @@ impl<'a> Formatter<'a> { } fn format_newline_reserved_word(&mut self, token: &Token<'_>, query: &mut String) { - if !self.inline_block.is_active() - && self - .options - .max_inline_arguments - .is_none_or(|limit| limit < self.indentation.span()) + // line comments force a newline + let after_line_comment = self + .previous_non_whitespace_token(1) + .is_some_and(|t| t.kind == TokenKind::LineComment); + + if after_line_comment + || !self.inline_block.is_active() + && self + .options + .max_inline_arguments + .is_none_or(|limit| limit < self.indentation.span()) { + // We inlined something to the top level let's increase the indentation now + if let Some((_, s)) = self.indentation.previous_top_level_reserved() { + if !s.newline_after { + self.indentation.increase_top_level(s.clone()); + } + } + + // let's undo the line comment indentation + if after_line_comment { + self.trim_spaces_end(query); + } + self.add_new_line(query); } else { self.trim_spaces_end(query); @@ -373,14 +391,15 @@ impl<'a> Formatter<'a> { let previous_non_whitespace_token = self.previous_non_whitespace_token(1); let fold_in_top_level = !inlined && self.options.max_inline_top_level.is_some() - && self - .previous_non_whitespace_token(1) - .is_some_and(|t| t.kind == TokenKind::ReservedTopLevel) + && previous_non_whitespace_token.is_some_and(|t| t.kind == TokenKind::ReservedTopLevel) && self .indentation .previous_top_level_reserved() .is_some_and(|(_, span)| { - span.blocks == 1 && span.newline_after && span.arguments == 1 + // We can have the two following situations + // top level ( block ) + // top level ( block ) AS word (args, ...) + span.blocks <= 2 && span.newline_after && span.arguments == 1 }); // Take out the preceding space unless there was whitespace there in the original query @@ -503,7 +522,7 @@ impl<'a> Formatter<'a> { if let Some((_, span)) = self.indentation.previous_top_level_reserved() { let limit = self.options.max_inline_arguments.unwrap_or(0); - if limit > span.full_span { + if limit >= span.full_span { return; } } @@ -700,18 +719,19 @@ impl<'a> Formatter<'a> { full_span += token.value.len(); } + let limit = self.options.max_inline_top_level.unwrap_or(0); // if we are inside an inline block we decide our behaviour as if were inline let block_len = self.inline_block.cur_len(); - let (newline_before, newline_after) = if block_len > 0 { - let limit = self.options.max_inline_top_level.unwrap_or(0); - (limit < block_len, limit < full_span) + + let newline_before = block_len == 0 || limit < block_len; + + // if we are going to format a list of arguments take in account also the limit for + // arguments + let arguments_limit = self.options.max_inline_arguments.unwrap_or(0); + let newline_after = if arguments > 1 && arguments_limit != 0 { + arguments_limit.min(limit) < full_span } else { - ( - true, - self.options - .max_inline_top_level - .is_none_or(|limit| limit < full_span), - ) + limit < full_span }; SpanInfo { diff --git a/src/indentation.rs b/src/indentation.rs index 718c07a..d58f0c9 100644 --- a/src/indentation.rs +++ b/src/indentation.rs @@ -76,6 +76,8 @@ impl<'a> Indentation<'a> { folded = kind == Some(IndentType::FoldedBlock); if kind != Some(IndentType::Top) { break; + } else { + self.top_level_span.pop(); } } folded diff --git a/src/lib.rs b/src/lib.rs index 9734e70..4a9f059 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2256,8 +2256,7 @@ mod tests { FROM table ) SELECT - b, - field + b, field FROM a, aa;" }; assert_eq!(format(input, &QueryParams::None, &options), expected); @@ -2480,7 +2479,7 @@ from SELECT true FROM bar WHERE bar.foo = $99 - AND bar.foo > $100 + AND bar.foo > $100 ), c = CASE WHEN $6 THEN NULL ELSE COALESCE($7, c) END, d = CASE