@@ -341,6 +341,7 @@ fn process_node(
341341 process_body ( input, node, render_elements)
342342 }
343343 GDScriptNodeKind :: Lambda => process_lambda ( input, node, render_elements) ,
344+ GDScriptNodeKind :: Function => process_function ( input, node, render_elements) ,
344345 GDScriptNodeKind :: SetGet => process_setget ( input, node, render_elements) ,
345346 GDScriptNodeKind :: ParenthesizedExpression => {
346347 process_parenthesized_expression ( input, node, render_elements)
@@ -352,6 +353,70 @@ fn process_node(
352353 }
353354}
354355
356+ /// Groups a function header (the declaration line/first line) separately from
357+ /// its body so the complete header, including the return type, is treated as
358+ /// one unit when deciding whether parameters need to be wrapped onto multiple
359+ /// lines.
360+ fn process_function (
361+ input : & ParseInput ,
362+ node : tree_sitter:: Node ,
363+ render_elements : & mut Vec < RenderElement > ,
364+ ) {
365+ let mut has_disabled_region = false ;
366+ let mut region_index = 0 ;
367+ while region_index < input. disabled_regions . len ( ) {
368+ let region = input. disabled_regions [ region_index] ;
369+ if region. start < node. end_byte ( ) && region. end > node. start_byte ( ) {
370+ has_disabled_region = true ;
371+ break ;
372+ }
373+ region_index += 1 ;
374+ }
375+ // Disabled regions (fmt: off / fmt: on comment pairs) can overlap a
376+ // function anywhere, so they can be anywhere in the middle of the function
377+ // AST. If we encounter one we fall back to the generic formatter, which
378+ // handles disabled regions correctly.
379+ if has_disabled_region {
380+ process_children_with_spacing ( input, node, render_elements) ;
381+ return ;
382+ }
383+
384+ let group_index = begin_group ( render_elements) ;
385+ let mut previous: Option < tree_sitter:: Node > = None ;
386+ let mut child_index = 0 ;
387+ while child_index < node. child_count ( ) {
388+ if let Some ( child) = node. child ( child_index as u32 ) {
389+ let child_kind = GDScriptNodeKind :: get_kind_from_ast_node ( child) ;
390+ if child_kind == GDScriptNodeKind :: Body {
391+ finish_group ( render_elements, group_index) ;
392+ if let Some ( previous_child) = previous {
393+ process_separator_between_sibling_nodes (
394+ GDScriptNodeKind :: Function ,
395+ & previous_child,
396+ & child,
397+ render_elements,
398+ ) ;
399+ }
400+ process_node ( input, child, render_elements) ;
401+ return ;
402+ }
403+
404+ if let Some ( previous_child) = previous {
405+ process_separator_between_sibling_nodes (
406+ GDScriptNodeKind :: Function ,
407+ & previous_child,
408+ & child,
409+ render_elements,
410+ ) ;
411+ }
412+ process_node ( input, child, render_elements) ;
413+ previous = Some ( child) ;
414+ }
415+ child_index += 1 ;
416+ }
417+ finish_group ( render_elements, group_index) ;
418+ }
419+
355420/// Returns the string with the preferred string delimiters if the user used the
356421/// option to prefer a specific quote style (' or "). Returns `None` when the
357422/// original string already uses the preferred quote style to avoid unnecessary
@@ -1513,7 +1578,15 @@ fn process_container(
15131578 return ;
15141579 }
15151580
1516- let group_index = begin_group ( render_elements) ;
1581+ let is_function_parameters = node_kind == GDScriptNodeKind :: Parameters
1582+ && node. parent ( ) . is_some_and ( |parent| {
1583+ GDScriptNodeKind :: get_kind_from_ast_node ( parent) == GDScriptNodeKind :: Function
1584+ } ) ;
1585+ let group_index = if is_function_parameters {
1586+ None
1587+ } else {
1588+ Some ( begin_group ( render_elements) )
1589+ } ;
15171590
15181591 if let Some ( open) = node. child ( 0 ) {
15191592 process_node ( input, open, render_elements) ;
@@ -1756,7 +1829,9 @@ fn process_container(
17561829 process_node ( input, close, render_elements) ;
17571830 }
17581831
1759- finish_group ( render_elements, group_index) ;
1832+ if let Some ( group_index) = group_index {
1833+ finish_group ( render_elements, group_index) ;
1834+ }
17601835}
17611836
17621837/// Formats ParenthesizedExpression nodes with a Group. Falls back to
0 commit comments