diff --git a/crates/emmylua_formatter/src/formatter/expr.rs b/crates/emmylua_formatter/src/formatter/expr.rs index 6fdd2302d..bd8ce7eaa 100644 --- a/crates/emmylua_formatter/src/formatter/expr.rs +++ b/crates/emmylua_formatter/src/formatter/expr.rs @@ -1366,7 +1366,7 @@ fn format_single_arg_call_without_parens( .is_single_arg_no_parens() .then(|| args_list.get_single_arg_expr()) .flatten(), - SingleArgCallParens::Omit => args_list.get_single_arg_expr(), + SingleArgCallParens::Omit => sole_arg_expr(args_list), }?; Some(match single_arg { @@ -1380,6 +1380,22 @@ fn format_single_arg_call_without_parens( }) } +/// The argument of a parenthesized call that has exactly one argument and no comments, +/// i.e. one whose parentheses can be dropped without losing anything. +fn sole_arg_expr(args_list: &LuaCallArgList) -> Option { + let mut args = args_list.get_args(); + let arg = args.next()?; + if args.next().is_some() + || args_list + .syntax() + .children() + .any(|child| LuaComment::cast(child).is_some()) + { + return None; + } + LuaSingleArgExpr::cast(arg.syntax().clone()) +} + fn format_table_expr(ctx: &FormatContext, plan: &FormatPlan, expr: &LuaTableExpr) -> Vec { let has_direct_comments = expr .syntax() diff --git a/crates/emmylua_formatter/src/test/config_tests.rs b/crates/emmylua_formatter/src/test/config_tests.rs index 118e5484e..da5e1bfdd 100644 --- a/crates/emmylua_formatter/src/test/config_tests.rs +++ b/crates/emmylua_formatter/src/test/config_tests.rs @@ -486,6 +486,50 @@ local t = { ); } + #[test] + fn test_single_arg_call_parens_omit_keeps_parens_for_multiple_args() { + let config = LuaFormatConfig { + output: OutputConfig { + single_arg_call_parens: SingleArgCallParens::Omit, + ..Default::default() + }, + ..Default::default() + }; + + for code in [ + "print(\"a\", \"b\")\n", + "local n = select(\"#\", ...)\n", + "obj:method({ 1 }, 2)\n", + // the string/table is not the first argument + "foo(x, \"a\")\n", + "foo(1, { 2 })\n", + ] { + assert_format_with_config!(code, code, config.clone()); + } + } + + #[test] + fn test_single_arg_call_parens_omit_keeps_parens_around_a_comment() { + let config = LuaFormatConfig { + output: OutputConfig { + single_arg_call_parens: SingleArgCallParens::Omit, + ..Default::default() + }, + ..Default::default() + }; + + // same layout as with the default `Preserve`: the comment keeps the call parenthesized + assert_format_with_config!( + r#"foo("a" --[[note]]) +"#, + r#"foo( + "a" --[[note]] +) +"#, + config + ); + } + #[test] fn test_simple_lambda_single_line_always_collapses_eligible_multiline_lambda() { let config = LuaFormatConfig {