Repository: nix-community/nixpkgs-fmt (rust)

Issue:
sample: function body indent
I think the function body shouldn't be indented if the arguments are on the same level.

## Input
```nix
let
  aaa =
 {foo,bar}:
              foo+bar
;
bbb = {foo,bar}:
              foo+bar
;
in
  null
```

## Output
```nix
let
  aaa =
    { foo, bar }:
      foo + bar
  ;
  bbb = { foo, bar }:
    foo + bar
  ;
in
null

```

## Desired output

```nix
let
  aaa =
    { foo, bar }:
    foo + bar
    ;
  bbb = { foo, bar }:
    foo + bar
    ;
in
null
```


Pull request:
fix #151 function body indent and small fix on let ... in
This PR fixes:
1. Indentation inside function body (lambda pattern);
2. Additional test data on `let .. in` to fit the indentation problem inside parenthesis. This is a good fix actually, because it avoids too much rule with regard to indentation.
3. Adjust flake.nix with the new indentation of body function rule.





Patch:
diff --git a/flake.nix b/flake.nix
index a816451..f3ffa09 100644
--- a/flake.nix
+++ b/flake.nix
@@ -20,38 +20,38 @@
 
         packages = forAllSystems (
           system:
-            {
-              nixpkgs-fmt = (
-                import nixpkgs {
-                  inherit system;
-                  overlays = [
-                    naerskOverlay
-                    self.overlay
-                  ];
-                }
-              ).nixpkgs-fmt;
-            }
+          {
+            nixpkgs-fmt = (
+              import nixpkgs {
+                inherit system;
+                overlays = [
+                  naerskOverlay
+                  self.overlay
+                ];
+              }
+            ).nixpkgs-fmt;
+          }
         );
 
 
         defaultPackage = forAllSystems (
           system:
-            self.packages.${system}.nixpkgs-fmt
+          self.packages.${system}.nixpkgs-fmt
         );
 
         apps = forAllSystems (
           system:
-            {
-              nixpkgs-fmt = {
-                type = "app";
-                program = "${self.defaultPackage.${system}}/bin/nixpkgs-fmt";
-              };
-            }
+          {
+            nixpkgs-fmt = {
+              type = "app";
+              program = "${self.defaultPackage.${system}}/bin/nixpkgs-fmt";
+            };
+          }
         );
 
         defaultApp = forAllSystems (
           system:
-            self.apps.${system}.nixpkgs-fmt
+          self.apps.${system}.nixpkgs-fmt
         );
 
       };
diff --git a/src/rules.rs b/src/rules.rs
index 3f79a01..8fc56c9 100644
--- a/src/rules.rs
+++ b/src/rules.rs
@@ -60,7 +60,7 @@ pub(crate) fn spacing() -> SpacingDsl {
         .inside(NODE_LIST).between(TOKEN_COMMENT, VALUES).single_space_or_newline()
 
         .test("( 92 )", "(92)")
-        .inside(NODE_PAREN).after(T!["("]).no_space_or_newline()
+        .inside(NODE_PAREN).after(T!["("]).no_space_or_optional_newline()
         .inside(NODE_PAREN).before(T![")"]).no_space_or_newline()
 
         .test("{foo = 92;}", "{ foo = 92; }")
@@ -138,7 +138,7 @@ pub(crate) fn spacing() -> SpacingDsl {
         })
         .add_rule(dsl::SpacingRule {
             name: None,
-            pattern: p(TOKEN_LET) & p(let_contain_linebreak_pattern) & p(let_inside_lambda_pattern),
+            pattern: p(TOKEN_LET) & p(let_contain_linebreak_pattern) & p(let_inside_lambda_or_paren),
             space: dsl::Space { loc: dsl::SpaceLoc::Before, value: dsl::SpaceValue::Newline }
         })
         .add_rule(dsl::SpacingRule {
@@ -197,16 +197,25 @@ fn let_contain_linebreak_pattern(element: &SyntaxElement) -> bool {
     find(element) == Some(true)
 }
 
-fn let_inside_lambda_pattern(element: &SyntaxElement) -> bool {
+fn let_inside_lambda_or_paren(element: &SyntaxElement) -> bool {
     fn find(element: &SyntaxElement) -> Option<bool> {
         let parent_let = get_parent(element)?;
         let inside_lambda_pattern =
             prev_non_whitespace_parent(element)?.into_token()?.text().contains(':');
+        let inside_paren_pattern =
+            prev_non_whitespace_parent(element)?.into_token()?.text().contains('(');
+        let inside_assign_pattern =
+            prev_non_whitespace_parent(element)?.into_token()?.text().contains('=');
         let prev_let_linebreak_pattern = match parent_let.prev_sibling_or_token()? {
             NodeOrToken::Node(_) => false,
             NodeOrToken::Token(it) => it.text().contains('\n'),
         };
-        Some(prev_let_linebreak_pattern || inside_lambda_pattern)
+        Some(
+            prev_let_linebreak_pattern
+                || inside_lambda_pattern
+                || inside_paren_pattern
+                || inside_assign_pattern,
+        )
     }
 
     find(element) == Some(true)
@@ -256,7 +265,7 @@ pub(crate) fn indentation() -> IndentDsl {
 
         .rule("Indent parenthesized expressions")
             .inside(NODE_PAREN)
-            .not_matching([T!["("], T![")"]])
+            .not_matching([T!["("],T![")"]])
             .set(Indent)
             .test(r#"
                 (
@@ -355,8 +364,8 @@ pub(crate) fn indentation() -> IndentDsl {
             "#)
 
         .rule("Indent lambda body")
-            .inside(p(NODE_LAMBDA) & p(not_on_top_level))
-            .not_matching([NODE_LAMBDA, TOKEN_COMMENT])
+            .inside(p(NODE_LAMBDA) & p(not_on_top_level) & p(inline_lambda)) //& p(align_comment)
+            //.not_matching()
             .set(Indent)
             .test(r#"
                 {}:
@@ -376,7 +385,7 @@ pub(crate) fn indentation() -> IndentDsl {
                     bar:
                     # describe baz
                     baz:
-                      fnbody;
+                    fnbody;
                 }
             "#)
 
@@ -469,6 +478,13 @@ pub(crate) fn indentation() -> IndentDsl {
     dsl
 }
 
+fn inline_lambda(element: &SyntaxElement) -> bool {
+    prev_token_sibling(element).map(|t| t.text().contains("\n")) != Some(true)
+}
+
+fn align_comment(element: &SyntaxElement) -> bool {
+    prev_token_sibling(element).map(|t| t.text().contains("\n")) != Some(true)
+}
 fn not_on_top_level(element: &SyntaxElement) -> bool {
     !on_top_level(element)
 }


Test patch:
diff --git a/test_data/curried_fn_no_indent.good.nix b/test_data/curried_fn_no_indent.good.nix
index 2c4c76d..e414687 100644
--- a/test_data/curried_fn_no_indent.good.nix
+++ b/test_data/curried_fn_no_indent.good.nix
@@ -2,5 +2,5 @@
   foo =
     bar:
     baz:
-      fnbody;
+    fnbody;
 }
diff --git a/test_data/indent_paren.bad.nix b/test_data/indent_paren.bad.nix
index d6835eb..01ae71b 100644
--- a/test_data/indent_paren.bad.nix
+++ b/test_data/indent_paren.bad.nix
@@ -8,6 +8,6 @@
 );
   xxx = listToAttrs (
   concatMap (name:
-    let a = 4; in 5
+  let a = 4; in 5
 ));
 }
diff --git a/test_data/indent_paren.good.nix b/test_data/indent_paren.good.nix
index be99101..24ec6ec 100644
--- a/test_data/indent_paren.good.nix
+++ b/test_data/indent_paren.good.nix
@@ -7,9 +7,8 @@
     )
   );
   xxx = listToAttrs (
-    concatMap (
-      name:
-        let a = 4; in 5
+    concatMap (name:
+      let a = 4; in 5
     )
   );
 }
diff --git a/test_data/issue-125.bad.nix b/test_data/issue-125.bad.nix
index 3010205..bcd4f91 100644
--- a/test_data/issue-125.bad.nix
+++ b/test_data/issue-125.bad.nix
@@ -4,7 +4,13 @@ foo = let x = y; in
 z;
 # all in one line
 bar = let x = 3; in x;
-baz = v: let x = 3; in
+faz = let x = 3;
+y = 4; in x;
+baz = let x = 3;
+in x;
+qaz = let x = 3; in
+x;
+paz = v: let x = 3; in
 x;
 qux = v: let y = 3; in y;
 nux = v: let x = 3;
diff --git a/test_data/issue-125.good.nix b/test_data/issue-125.good.nix
index 35f3350..a3de059 100644
--- a/test_data/issue-125.good.nix
+++ b/test_data/issue-125.good.nix
@@ -4,7 +4,18 @@ let
     z;
   # all in one line
   bar = let x = 3; in x;
-  baz = v: let x = 3; in
+  faz =
+    let
+      x = 3;
+      y = 4;
+    in x;
+  baz =
+    let
+      x = 3;
+    in x;
+  qaz = let x = 3; in
+    x;
+  paz = v: let x = 3; in
     x;
   qux = v: let y = 3; in y;
   nux = v:
diff --git a/test_data/issue-151.bad.nix b/test_data/issue-151.bad.nix
new file mode 100644
index 0000000..e095408
--- /dev/null
+++ b/test_data/issue-151.bad.nix
@@ -0,0 +1,18 @@
+let
+  aaa =
+ {foo,bar}:
+              foo+bar
+;
+bbb = {foo,bar}:
+              foo+bar
+;
+ccc =
+  {foo,bar}:
+  let x = foo + bar; in x;
+ddd =
+  {foo,bar}:
+             {
+    inherit foo bar;
+             };
+in
+  null
diff --git a/test_data/issue-151.good.nix b/test_data/issue-151.good.nix
new file mode 100644
index 0000000..37b9063
--- /dev/null
+++ b/test_data/issue-151.good.nix
@@ -0,0 +1,18 @@
+let
+  aaa =
+    { foo, bar }:
+    foo + bar
+  ;
+  bbb = { foo, bar }:
+    foo + bar
+  ;
+  ccc =
+    { foo, bar }:
+    let x = foo + bar; in x;
+  ddd =
+    { foo, bar }:
+    {
+      inherit foo bar;
+    };
+in
+null
diff --git a/test_data/issue-152.bad.nix b/test_data/issue-152.bad.nix
new file mode 100644
index 0000000..864c8cf
--- /dev/null
+++ b/test_data/issue-152.bad.nix
@@ -0,0 +1,19 @@
+let
+id =
+x:
+# comment
+x;
+foo = x:
+  #comment
+  x+x;
+bar = x: let y = x;
+in
+  #comment
+  x;
+baz = x:
+#comment
+  y:
+  #comment
+  foo+bar;
+in
+id 1
diff --git a/test_data/issue-152.good.nix b/test_data/issue-152.good.nix
new file mode 100644
index 0000000..bbeff49
--- /dev/null
+++ b/test_data/issue-152.good.nix
@@ -0,0 +1,21 @@
+let
+  id =
+    x:
+    # comment
+    x;
+  foo = x:
+    #comment
+    x + x;
+  bar = x:
+    let
+      y = x;
+    in
+      #comment
+      x;
+  baz = x:
+    #comment
+    y:
+    #comment
+    foo + bar;
+in
+id 1