Repository: prettier/prettier (JavaScript)

Issue:
Weird wrapping for SCSS @use rules
<!--

BEFORE SUBMITTING AN ISSUE:

1.  Search for your issue on GitHub: https://github.com/prettier/prettier/issues
    A large number of opened issues are duplicates of existing issues.
    If someone has already opened an issue for what you are experiencing,
    you do not need to open a new issue — please add a 👍 reaction to the
    existing issue instead.

2.  We get a lot of requests for adding options, but Prettier is
    built on the principle of being opinionated about code formatting.
    This means we add options only in the case of strict technical necessity.
    Find out more: https://prettier.io/docs/en/option-philosophy.html

Don't fill the form below manually! Let a program create a report for you:

1. Go to https://prettier.io/playground
2. Paste your code and set options
3. Press the "Report issue" button in the lower right

-->

**Prettier 2.4.1**
[Playground link](https://prettier.io/playground/#N4Igxg9gdgLgprEAuEABArgZzgAgDpoBmAngDYDmAVgIYD0ARtdgTgO4CWMAFjgBR5QcQnABJC1ALbtSxALQTq7KEj4Dh6nACV09dgGsANGo1DNEehBgQjgkzkzFM8CbPTsbd+9SiZZ2AE7shB7CAJQhQmLQMLKscOzkXDAqAMwArAAMEaJcAIyyhNGx8YnJOJlZxpFcAEwFRXEJSSoV2SJcKfWwxU1lFQKhANwgBiAQAA4w7NCYyKDU-v4QrAAKCwizKNSkrNSOIyD0-tRgenAwAMqScAAySnDI4qTYo0cnZ5fjJ0rkyDD+6DgozgEnocAAJuCITdvOR0NRyHAAGIQfwKGBTKC-LboKwHJISUgAdS4nDgmC+YDgFw2nHYADdOMRkOBMLNRkoAjAVsdyApHtsXiBKJgAB4XH6kOAARXQlgeSCeQq+-gCLMwYDZB3GgVgRPY4O4yAAHFkQDqINgicdxiydeS4P56Q9RgBHOXwHkTTYgJiyKBwCEQg7+ODu9ihnkI-mKwVAkDYKR-AHxzCSmUehVK+Mwaj0fWGrjIGqjf6KUg-ADCEAkMZA5LSBywcAAKnnNtnRvTAQBJKBQ2AXMCBSYAQX7FxgZCzcYAvrOgA)

Not sure which version this was introduced.
Previously this did not happen.

But the current SCSS syntax using `@use` gets wrapped in a weird way.
The opening parentheses is wrapped with a indent, and also all of  the code inside it.

**Input:**

```scss
@use "@fylgja/base" with (
    $family-main: (
        Rubik,
        Roboto,
        system-ui,
        sans-serif,
    ),
    $font-weight: 350,
    $h1-font-weight: 500,
    $h2-font-weight: 500,
    $h3-font-weight: 500
);
```

**Output:**

```scss
@use "@fylgja/base" with
  (
    $family-main: (
      Rubik,
      Roboto,
      system-ui,
      sans-serif,
    ),
    $font-weight: 350,
    $h1-font-weight: 500,
    $h2-font-weight: 500,
    $h3-font-weight: 500
  );
```

**Expected behavior:**

```scss
@use "@fylgja/base" with (
    $family-main: (
        Rubik,
        Roboto,
        system-ui,
        sans-serif,
    ),
    $font-weight: 350,
    $h1-font-weight: 500,
    $h2-font-weight: 500,
    $h3-font-weight: 500
);
```



Hints:
hm, both looks good...
I think the indent should not be there @alexander-akait 
But it is also inconsistent with the SCSS map wrapping which does not wrap the opening parentheses to the next line

Patch:
diff --git a/src/language-css/printer-postcss.js b/src/language-css/printer-postcss.js
--- a/src/language-css/printer-postcss.js
+++ b/src/language-css/printer-postcss.js
@@ -74,6 +74,7 @@ const {
   isColorAdjusterFuncNode,
   lastLineHasInlineComment,
   isAtWordPlaceholderNode,
+  isConfigurationNode,
 } = require("./utils.js");
 const { locStart, locEnd } = require("./loc.js");
 
@@ -807,6 +808,19 @@ function genericPrint(path, options, print) {
           continue;
         }
 
+        if (
+          iNode.value === "with" &&
+          iNextNode &&
+          iNextNode.type === "value-paren_group" &&
+          iNextNode.open &&
+          iNextNode.open.value === "(" &&
+          iNextNode.close &&
+          iNextNode.close.value === ")"
+        ) {
+          parts.push(" ");
+          continue;
+        }
+
         // Be default all values go through `line`
         parts.push(line);
       }
@@ -872,6 +886,10 @@ function genericPrint(path, options, print) {
       const lastItem = getLast(node.groups);
       const isLastItemComment = lastItem && lastItem.type === "value-comment";
       const isKey = isKeyInValuePairNode(node, parentNode);
+      const isConfiguration = isConfigurationNode(node, parentNode);
+
+      const shouldBreak = isConfiguration || (isSCSSMapItem && !isKey);
+      const shouldDedent = isConfiguration || isKey;
 
       const printed = group(
         [
@@ -915,11 +933,11 @@ function genericPrint(path, options, print) {
           node.close ? print("close") : "",
         ],
         {
-          shouldBreak: isSCSSMapItem && !isKey,
+          shouldBreak,
         }
       );
 
-      return isKey ? dedent(printed) : printed;
+      return shouldDedent ? dedent(printed) : printed;
     }
     case "value-func": {
       return [
diff --git a/src/language-css/utils.js b/src/language-css/utils.js
--- a/src/language-css/utils.js
+++ b/src/language-css/utils.js
@@ -484,6 +484,30 @@ function isModuleRuleName(name) {
   return moduleRuleNames.has(name);
 }
 
+function isConfigurationNode(node, parentNode) {
+  if (
+    !node.open ||
+    node.open.value !== "(" ||
+    !node.close ||
+    node.close.value !== ")" ||
+    node.groups.some((group) => group.type !== "value-comma_group")
+  ) {
+    return false;
+  }
+  if (parentNode.type === "value-comma_group") {
+    const prevIdx = parentNode.groups.indexOf(node) - 1;
+    const maybeWithNode = parentNode.groups[prevIdx];
+    if (
+      maybeWithNode &&
+      maybeWithNode.type === "value-word" &&
+      maybeWithNode.value === "with"
+    ) {
+      return true;
+    }
+  }
+  return false;
+}
+
 module.exports = {
   getAncestorCounter,
   getAncestorNode,
@@ -539,4 +563,5 @@ module.exports = {
   stringifyNode,
   isAtWordPlaceholderNode,
   isModuleRuleName,
+  isConfigurationNode,
 };


Test patch:
diff --git a/tests/format/scss/configuration/__snapshots__/jsfmt.spec.js.snap b/tests/format/scss/configuration/__snapshots__/jsfmt.spec.js.snap
new file mode 100644
--- /dev/null
+++ b/tests/format/scss/configuration/__snapshots__/jsfmt.spec.js.snap
@@ -0,0 +1,94 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`use.scss - {"trailingComma":"none"} format 1`] = `
+====================================options=====================================
+parsers: ["scss"]
+printWidth: 80
+trailingComma: "none"
+                                                                                | printWidth
+=====================================input======================================
+@use "@fylgja/base" with (
+  $family-main: (
+  Rubik,
+    Roboto,
+    system-ui,
+    sans-serif,
+  ),
+  $font-weight: 350,
+  $h1-font-weight: 500,
+  $h2-font-weight: 500,
+  $h3-font-weight: 500
+);
+
+@use 'library' with (
+  $black: #222,
+  $border-radius: 0.1rem
+);
+
+=====================================output=====================================
+@use "@fylgja/base" with (
+  $family-main: (
+    Rubik,
+    Roboto,
+    system-ui,
+    sans-serif
+  ),
+  $font-weight: 350,
+  $h1-font-weight: 500,
+  $h2-font-weight: 500,
+  $h3-font-weight: 500
+);
+
+@use "library" with (
+  $black: #222,
+  $border-radius: 0.1rem
+);
+
+================================================================================
+`;
+
+exports[`use.scss format 1`] = `
+====================================options=====================================
+parsers: ["scss"]
+printWidth: 80
+                                                                                | printWidth
+=====================================input======================================
+@use "@fylgja/base" with (
+  $family-main: (
+  Rubik,
+    Roboto,
+    system-ui,
+    sans-serif,
+  ),
+  $font-weight: 350,
+  $h1-font-weight: 500,
+  $h2-font-weight: 500,
+  $h3-font-weight: 500
+);
+
+@use 'library' with (
+  $black: #222,
+  $border-radius: 0.1rem
+);
+
+=====================================output=====================================
+@use "@fylgja/base" with (
+  $family-main: (
+    Rubik,
+    Roboto,
+    system-ui,
+    sans-serif,
+  ),
+  $font-weight: 350,
+  $h1-font-weight: 500,
+  $h2-font-weight: 500,
+  $h3-font-weight: 500
+);
+
+@use "library" with (
+  $black: #222,
+  $border-radius: 0.1rem
+);
+
+================================================================================
+`;
diff --git a/tests/format/scss/configuration/jsfmt.spec.js b/tests/format/scss/configuration/jsfmt.spec.js
new file mode 100644
--- /dev/null
+++ b/tests/format/scss/configuration/jsfmt.spec.js
@@ -0,0 +1,2 @@
+run_spec(__dirname, ["scss"], { trailingComma: "none" });
+run_spec(__dirname, ["scss"]);
diff --git a/tests/format/scss/configuration/use.scss b/tests/format/scss/configuration/use.scss
new file mode 100644
--- /dev/null
+++ b/tests/format/scss/configuration/use.scss
@@ -0,0 +1,17 @@
+@use "@fylgja/base" with (
+  $family-main: (
+  Rubik,
+    Roboto,
+    system-ui,
+    sans-serif,
+  ),
+  $font-weight: 350,
+  $h1-font-weight: 500,
+  $h2-font-weight: 500,
+  $h3-font-weight: 500
+);
+
+@use 'library' with (
+  $black: #222,
+  $border-radius: 0.1rem
+);
diff --git a/tests/format/scss/quotes/__snapshots__/jsfmt.spec.js.snap b/tests/format/scss/quotes/__snapshots__/jsfmt.spec.js.snap
--- a/tests/format/scss/quotes/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/format/scss/quotes/__snapshots__/jsfmt.spec.js.snap
@@ -34,8 +34,10 @@ singleQuote: true
 =====================================output=====================================
 @use 'library';
 
-@use 'library' with
-  ($black: #222, $border-radius: 0.1rem $font-family: 'Helvetica, sans-serif');
+@use 'library' with (
+  $black: #222,
+  $border-radius: 0.1rem $font-family: 'Helvetica, sans-serif'
+);
 
 @use 'library' as *;
 
@@ -89,8 +91,10 @@ printWidth: 80
 =====================================output=====================================
 @use "library";
 
-@use "library" with
-  ($black: #222, $border-radius: 0.1rem $font-family: "Helvetica, sans-serif");
+@use "library" with (
+  $black: #222,
+  $border-radius: 0.1rem $font-family: "Helvetica, sans-serif"
+);
 
 @use "library" as *;