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

Issue:
sample: multi-line parenthesis
When a parenthesis is multi-line it should indent the inner bits.

## Input
```nix
{
  xxx = listToAttrs (
  concatMap (name:
    let a = 4; in 5
));
}
```

## Output
```nix
{
  xxx = listToAttrs (
  concatMap (name:
    let a = 4; in 5
  ));
}

```

## Desired output

```nix
{
  xxx = listToAttrs (
    concatMap (name:
      let a = 4; in 5
    )
  );
}

```

Pull request description:
Indent parens
closes #66



Patch:
diff --git a/src/engine.rs b/src/engine.rs
index feca150..5cf6d10 100644
--- a/src/engine.rs
+++ b/src/engine.rs
@@ -42,6 +42,19 @@ pub(crate) fn format(
             // No need to indent an element if it doesn't start a line
             continue;
         }
+
+        // In cases like
+        //
+        // ```nix
+        //   param:
+        //     body
+        // ```
+        //
+        // we only indent top-level node (lambda), and not it's first child (parameter)
+        if element.parent().map(|it| it.range().start()) == Some(element.range().start()) {
+            continue;
+        }
+
         let mut matching = indent_rule_set.matching(element);
         if let Some(rule) = matching.next() {
             rule.apply(element, &mut model, &anchor_set);
diff --git a/src/rules.rs b/src/rules.rs
index cda00b9..edca4ce 100644
--- a/src/rules.rs
+++ b/src/rules.rs
@@ -51,6 +51,10 @@ pub(crate) fn spacing() -> SpacingDsl {
         .inside(NODE_LIST).between(VALUES, VALUES).single_space_or_newline()
         .inside(NODE_LIST).between(VALUES, TOKEN_COMMENT).single_space_or_optional_newline()
 
+        // ( 92 ) => (92)
+        .inside(NODE_PAREN).after(T!["("]).no_space_or_newline()
+        .inside(NODE_PAREN).before(T![")"]).no_space_or_newline()
+
         // {foo = 92;} => { foo = 92; }
         .inside(NODE_SET).after(T!["{"]).single_space_or_newline()
         .inside(NODE_SET).before(T!["}"]).single_space_or_newline()
@@ -144,6 +148,7 @@ pub(crate) fn indentation() -> IndentDsl {
 
         .inside(NODE_INHERIT).indent([NODE_IDENT, NODE_INHERIT_FROM, T![;]])
         .inside(NODE_IF_ELSE).indent(VALUES)
+        .inside(NODE_PAREN).indent(VALUES)
 
         // FIXME: don't force indent if comment is on the first line
         .inside(ENTRY_OWNERS).indent(TOKEN_COMMENT)


Test patch:
diff --git a/test_data/indent_paren.bad.nix b/test_data/indent_paren.bad.nix
new file mode 100644
index 0000000..d6835eb
--- /dev/null
+++ b/test_data/indent_paren.bad.nix
@@ -0,0 +1,13 @@
+{
+  foo = (
+(
+(
+92
+)
+)
+);
+  xxx = listToAttrs (
+  concatMap (name:
+    let a = 4; in 5
+));
+}
diff --git a/test_data/indent_paren.good.nix b/test_data/indent_paren.good.nix
new file mode 100644
index 0000000..be99101
--- /dev/null
+++ b/test_data/indent_paren.good.nix
@@ -0,0 +1,15 @@
+{
+  foo = (
+    (
+      (
+        92
+      )
+    )
+  );
+  xxx = listToAttrs (
+    concatMap (
+      name:
+        let a = 4; in 5
+    )
+  );
+}