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

Issue:
sample: indented let body
whenever a let..in block is being added, it re-indents the whole body, creating a lot of noise in the diff.

Maybe it's worth special-casing at least for the top-level to not indent the body?

## Input
```nix
{ stdenv, fetchFromGitHub }:
let
pname = "hello";
version = "1.2.3";
in
stdenv.mkDerivation {
  inherit pname version;
  src = fetchFromGitHub {
    owner = "xxx";
    repo = pname;
    rev = version;
    sha256 = "...";
  };
}
```

## Output
```nix
{ stdenv, fetchFromGitHub }:
let
  pname = "hello";
  version = "1.2.3";
in
  stdenv.mkDerivation {
    inherit pname version;
    src = fetchFromGitHub {
      owner = "xxx";
      repo = pname;
      rev = version;
      sha256 = "...";
    };
  }

```

## Desired output

```nix
{ stdenv, fetchFromGitHub }:
let
  pname = "hello";
  version = "1.2.3";
in
stdenv.mkDerivation {
  inherit pname version;
  src = fetchFromGitHub {
    owner = "xxx";
    repo = pname;
    rev = version;
    sha256 = "...";
  };
}
```

Pull request:
don't indent top-level let
closes #92

Patch:
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index e6678bb..132eb87 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -15,7 +15,7 @@ repos:
        entry: nixpkgs-fmt --in-place
        language: rust
        files: \.nix$
-       minimum_pre_commit_version: 1.18.1
+       minimum_pre_commit_version: 1.14.2
        exclude: >
            (?x)^(
                nix/sources.nix|
diff --git a/shell.nix b/shell.nix
index 3900885..dfa0f7d 100644
--- a/shell.nix
+++ b/shell.nix
@@ -17,23 +17,23 @@ let
     targets = [ "wasm32-unknown-unknown" ];
   };
 in
-  pkgs.mkShell {
-    buildInputs = [
-      pkgs.cargo-fuzz
-      pkgs.gitAndTools.pre-commit
-      pkgs.mdsh
-      pkgs.openssl
-      pkgs.pkgconfig
-      pkgs.rustfmt
-      pkgs.wasm-pack
-      rust
-    ]
-    ++ stdenv.lib.optionals stdenv.isDarwin [
-         darwin.apple_sdk.frameworks.Security
-       ]
-    ;
+pkgs.mkShell {
+  buildInputs = [
+    pkgs.cargo-fuzz
+    pkgs.gitAndTools.pre-commit
+    pkgs.mdsh
+    pkgs.openssl
+    pkgs.pkgconfig
+    pkgs.rustfmt
+    pkgs.wasm-pack
+    rust
+  ]
+  ++ stdenv.lib.optionals stdenv.isDarwin [
+       darwin.apple_sdk.frameworks.Security
+     ]
+  ;
 
-    shellHook = ''
-      export PATH=$PWD/target/debug:$PATH
-      '';
-  }
+  shellHook = ''
+    export PATH=$PWD/target/debug:$PATH
+    '';
+}
diff --git a/src/pattern.rs b/src/pattern.rs
index 7801bf0..78335e1 100644
--- a/src/pattern.rs
+++ b/src/pattern.rs
@@ -80,6 +80,20 @@ impl ops::BitAnd for Pattern {
     }
 }
 
+/// `pat1 | pat2` operator
+impl ops::BitOr for Pattern {
+    type Output = Pattern;
+    fn bitor(self, other: Pattern) -> Pattern {
+        let kinds = match (self.kinds, other.kinds) {
+            (Some(lhs), Some(rhs)) => Some(lhs.union(&rhs).cloned().collect::<HashSet<_>>()),
+            (Some(it), None) | (None, Some(it)) => Some(it),
+            (None, None) => None,
+        };
+        let (p1, p2) = (self.pred, other.pred);
+        Pattern::new(kinds, move |element| p1(element) || p2(element))
+    }
+}
+
 /// Construct pattern from closure.
 impl<F> From<F> for Pattern
 where
diff --git a/src/rules.rs b/src/rules.rs
index 8e474e1..8ebfc0c 100644
--- a/src/rules.rs
+++ b/src/rules.rs
@@ -130,6 +130,8 @@ fn after_multiline_binop(node: &SyntaxElement) -> bool {
     };
 }
 
+/// A convenience function to convert something a pattern for use with `&` and
+/// `|` operators
 fn p(p: impl Into<Pattern>) -> Pattern {
     p.into()
 }
@@ -184,21 +186,41 @@ pub(crate) fn indentation() -> IndentDsl {
             "#)
 
         .rule("Indent let bindings")
-            .inside(NODE_LET_IN)
+            .inside(p(NODE_LET_IN) & p(not_on_top_level))
             .not_matching([T![let], T![in]])
             .set(Indent)
             .test(r#"
-                let
-                x = 1;
-                inherit z;
+                (
+                  let
+                  x = 1;
+                  inherit z;
                   in
                   x
+                )
+            "#, r#"
+                (
+                  let
+                    x = 1;
+                    inherit z;
+                  in
+                    x
+                )
+            "#)
+
+        .rule("Indent let top-level bindings")
+            .inside(p(NODE_LET_IN) & p(on_top_level))
+            .not_matching(p([T![let], T![in]]) | p(VALUES))
+            .set(Indent)
+            .test(r#"
+                let
+                x = 1;
+                in
+                x
             "#, r#"
                 let
                   x = 1;
-                  inherit z;
                 in
-                  x
+                x
             "#)
 
         .rule("Indent attribute value")


Test patch:
diff --git a/test_data/indent_let.good.nix b/test_data/indent_let.good.nix
index 8141353..04b44d2 100644
--- a/test_data/indent_let.good.nix
+++ b/test_data/indent_let.good.nix
@@ -3,4 +3,4 @@ let
   y = 2;
   inherit z;
 in
-  x + y + z
+x + y + z
diff --git a/test_data/issue-83-1.good.nix b/test_data/issue-83-1.good.nix
index 592c6ae..a24f496 100644
--- a/test_data/issue-83-1.good.nix
+++ b/test_data/issue-83-1.good.nix
@@ -3,4 +3,4 @@ let
     foo
     '';
 in
-  a
+a
diff --git a/test_data/top_level_let.bad.nix b/test_data/top_level_let.bad.nix
new file mode 100644
index 0000000..de20e81
--- /dev/null
+++ b/test_data/top_level_let.bad.nix
@@ -0,0 +1,14 @@
+{ stdenv, fetchFromGitHub }:
+let
+pname = "hello";
+version = "1.2.3";
+in
+stdenv.mkDerivation {
+  inherit pname version;
+  src = fetchFromGitHub {
+    owner = "xxx";
+    repo = pname;
+    rev = version;
+    sha256 = "...";
+  };
+}
diff --git a/test_data/top_level_let.good.nix b/test_data/top_level_let.good.nix
new file mode 100644
index 0000000..80abb71
--- /dev/null
+++ b/test_data/top_level_let.good.nix
@@ -0,0 +1,14 @@
+{ stdenv, fetchFromGitHub }:
+let
+  pname = "hello";
+  version = "1.2.3";
+in
+stdenv.mkDerivation {
+  inherit pname version;
+  src = fetchFromGitHub {
+    owner = "xxx";
+    repo = pname;
+    rev = version;
+    sha256 = "...";
+  };
+}