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

Issue:
WASM Demo: show diff
I tested it with a package i created, but see no diff. So maybe my code is perfect (i hope :D), but i might not see the diff. So it would be helpful to highlight the diff.

Pull request description:
wasm: add diff output
Fixes #35 

Patch:
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 132eb87..e6678bb 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.14.2
+       minimum_pre_commit_version: 1.18.1
        exclude: >
            (?x)^(
                nix/sources.nix|
diff --git a/Cargo.lock b/Cargo.lock
index bcc3534..25f6257 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -73,6 +73,11 @@ dependencies = [
  "wasm-bindgen 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "difflib"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 name = "lazy_static"
 version = "1.3.0"
@@ -110,6 +115,7 @@ name = "nixpkgs-fmt-wasm"
 version = "0.1.0"
 dependencies = [
  "console_error_panic_hook 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "difflib 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "nixpkgs-fmt 0.1.0",
  "wasm-bindgen 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
  "wee_alloc 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -323,6 +329,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33"
 "checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
 "checksum console_error_panic_hook 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211"
+"checksum difflib 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8"
 "checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"
 "checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba"
 "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
diff --git a/shell.nix b/shell.nix
index dfa0f7d..3900885 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 78335e1..7801bf0 100644
--- a/src/pattern.rs
+++ b/src/pattern.rs
@@ -80,20 +80,6 @@ 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 8ebfc0c..8e474e1 100644
--- a/src/rules.rs
+++ b/src/rules.rs
@@ -130,8 +130,6 @@ 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()
 }
@@ -186,41 +184,21 @@ pub(crate) fn indentation() -> IndentDsl {
             "#)
 
         .rule("Indent let bindings")
-            .inside(p(NODE_LET_IN) & p(not_on_top_level))
+            .inside(NODE_LET_IN)
             .not_matching([T![let], T![in]])
             .set(Indent)
-            .test(r#"
-                (
-                  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
+                inherit z;
+                  in
+                  x
             "#, r#"
                 let
                   x = 1;
+                  inherit z;
                 in
-                x
+                  x
             "#)
 
         .rule("Indent attribute value")
diff --git a/wasm/Cargo.toml b/wasm/Cargo.toml
index 6ed3e61..1013ca3 100644
--- a/wasm/Cargo.toml
+++ b/wasm/Cargo.toml
@@ -14,7 +14,8 @@ repository = "https://github.com/nix-community/nixpkgs-fmt"
 crate-type = ["cdylib"]
 
 [dependencies]
+console_error_panic_hook = "0.1.6"
+difflib = "0.4.0"
 nixpkgs-fmt = { "path" = "../." }
 wasm-bindgen = "0.2"
 wee_alloc = "0.4.4"
-console_error_panic_hook = "0.1.6"
diff --git a/wasm/index.html b/wasm/index.html
index 3f4447a..b46cdd0 100644
--- a/wasm/index.html
+++ b/wasm/index.html
@@ -49,6 +49,10 @@
           <dt><label for=reformat-output>Output</label></dt>
           <dd>
             <pre id=reformat-output></pre>
+            <label>
+              show diff:
+              <input id=reformat-output-format value=diff type=checkbox>
+            </label>
           </dd>
         </dl>
       </div>
@@ -78,14 +82,17 @@
     const inputEl = document.getElementById("reformat-input")
     const inputFileEl = document.getElementById("reformat-input-file")
     const outputEl = document.getElementById("reformat-output")
+    const outputFormatEl = document.getElementById("reformat-output-format")
     const issueBodyEl = document.getElementById("issue-body")
 
     const reformat = () => {
-      console.log("reformatting...")
       const input = inputEl.value
+      const format = outputFormatEl.checked ? "diff" : "normal"
+      console.log("reformatting format=" + format)
+
       var output
       try {
-        output = reformat_string(input)
+        output = reformat_string(input, format)
       } catch (err) {
         output = err
       }
@@ -124,9 +131,8 @@ ${output}
       inputEl.onchange = reformat
       inputEl.onkeyup = reformat
       inputEl.onpaste = reformat
-      reformat()
+      outputFormatEl.onchange = reformat
 
-      // load file
       inputFileEl.onchange = () => {
         console.log("loading file", inputFileEl)
         const file = inputFileEl.files[0]
@@ -137,6 +143,8 @@ ${output}
         }
         fr.readAsText(file)
       }
+
+      reformat()
     }
 
     run();
diff --git a/wasm/src/lib.rs b/wasm/src/lib.rs
index de24309..6d7f3c1 100644
--- a/wasm/src/lib.rs
+++ b/wasm/src/lib.rs
@@ -13,6 +13,15 @@ pub fn main() -> Result<(), JsValue> {
 }
 
 #[wasm_bindgen]
-pub fn reformat_string(text: &str) -> String {
-    nixpkgs_fmt::reformat_string(text)
+pub fn reformat_string(text: &str, format: &str) -> String {
+    let out = nixpkgs_fmt::reformat_string(text);
+
+    if format == "diff" {
+        let first_text = text.lines().collect::<Vec<&str>>();
+        let second_text = out.lines().collect::<Vec<&str>>();
+        let diff = difflib::unified_diff(&first_text, &second_text, "Input", "Output", "", "", 3);
+        return [diff[0..3].join(""), diff[3..].join("\n")].join("");
+    } else {
+        return out;
+    }
 }


Test patch:
diff --git a/test_data/indent_let.good.nix b/test_data/indent_let.good.nix
index 04b44d2..8141353 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 a24f496..592c6ae 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
deleted file mode 100644
index de20e81..0000000
--- a/test_data/top_level_let.bad.nix
+++ /dev/null
@@ -1,14 +0,0 @@
-{ 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
deleted file mode 100644
index 80abb71..0000000
--- a/test_data/top_level_let.good.nix
+++ /dev/null
@@ -1,14 +0,0 @@
-{ stdenv, fetchFromGitHub }:
-let
-  pname = "hello";
-  version = "1.2.3";
-in
-stdenv.mkDerivation {
-  inherit pname version;
-  src = fetchFromGitHub {
-    owner = "xxx";
-    repo = pname;
-    rev = version;
-    sha256 = "...";
-  };
-}