Repository: prettier/prettier (JavaScript)

Issue:
Idempotent issue for SCSS map
**Prettier 2.8.1**
[Playground link](https://prettier.io/playground/#N4Igxg9gdgLgprEAuEASAJgSwM4AcA2AhgJ4C0ARgE5yEDWuEms2SABALaG6npxzfs4lAOZwAFAB0orVpOkzWEkAA9spaPmJK2SjcVbYw1BK0JR0szstIB3TOhgALNgGJgnbqJhjUwyvYpqOgYmGGwAGkUQbHYlAEpSAEYAXzilcKkZOIz5DBwCEkCaekZmKTiAbhBwkAhcGExobGRQQkpKCBsABTaEZpRCfBsSZpqqQjBaOBgAZUJBABkmOGQAM0HsODHKCanZ3AmmYWQYSgBXLZA4dnI4dF50BbNhM8JRADEISk4YBqhjgZnGAQaogRwwdj4ADqjkw8DwEzgMz6cMwADc4cRkOBsKMQExNpQYF0dsJOGsNpcAFbYZQzI74OAARTOEHgFPwmxqB0ohOxhlxoNw-lgUPsTmQAA4AAzcjqbKE7XDY4VwQlolY1ACOrPgJLq-RAhDUUD4D1B1B1mGoJLe5KQ605l027EwJ3OzoZcAAgr9-OQgXAukIlqaOVzol6WWyVg7KTUYIRyGKHI5kAAmBM7TD4I4AYQg7HtV2wAFZQWdNgAVJP9R0RtEXACS5gQsyMmHq3vMMxgxEZ4bgyWSQA)
<!-- prettier-ignore -->
```sh
--parser scss
```

**Input:**
<!-- prettier-ignore -->
```scss
$display-breakpoints: map-deep-merge(
  (
    "xs-only": "only screen and (max-width: #{map-get($grid-breakpoints, "sm")-1})",
  ),
  $display-breakpoints
);
```

**Output:**
<!-- prettier-ignore -->
```scss
$display-breakpoints: map-deep-merge(
  (
    "xs-only": "only screen and (max-width: #{map-get($grid-breakpoints, "sm")-1})"
  ),
  $display-breakpoints
);

```

**Second Output:**
<!-- prettier-ignore -->
```scss
$display-breakpoints: map-deep-merge(
  (
    "xs-only": "only screen and (max-width: #{map-get($grid-breakpoints, " sm
      ")-1})",
  ),
  $display-breakpoints
);

```

**Expected behavior:**

same as input

**Related:**

- https://github.com/prettier/prettier/issues/9128
- https://github.com/prettier/prettier/issues/13984
Fix function argument list in SCSS maps
## Description

<!-- Please provide a brief summary of your changes: -->

Fix #13984

## Checklist

<!-- Please ensure you’ve done all of these things (if applicable). -->
<!-- You can replace the `[ ]` with `[x]` to mark each task as done. -->

- [ ] I’ve added tests to confirm my change works.
- [ ] (If changing the API or CLI) I’ve documented the changes I’ve made (in the `docs/` directory).
- [ ] (If the change is user-facing) I’ve added my changes to `changelog_unreleased/*/XXXX.md` file following `changelog_unreleased/TEMPLATE.md`.
- [ ] I’ve read the [contributing guidelines](https://github.com/prettier/prettier/blob/main/CONTRIBUTING.md).

<!-- Please DO NOT remove the playground link -->

**✨[Try the playground for this PR](https://prettier.io/playground-redirect)✨**



Hints:

Patch:
diff --git a/src/language-css/parser-postcss.js b/src/language-css/parser-postcss.js
--- a/src/language-css/parser-postcss.js
+++ b/src/language-css/parser-postcss.js
@@ -122,23 +122,6 @@ function parseValueNode(valueNode, options) {
       parenGroupStack.pop();
       parenGroup = getLast(parenGroupStack);
     } else if (node.type === "comma") {
-      if (commaGroup.groups.length > 1) {
-        for (const group of commaGroup.groups) {
-          // if css interpolation
-          if (
-            group.value &&
-            typeof group.value === "string" &&
-            group.value.includes("#{")
-          ) {
-            commaGroup.groups = [
-              stringifyNode({
-                groups: commaGroup.groups,
-              }).trim(),
-            ];
-            break;
-          }
-        }
-      }
       parenGroup.groups.push(commaGroup);
       commaGroup = {
         groups: [],
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
@@ -547,6 +547,7 @@ function genericPrint(path, options, print) {
 
       let insideSCSSInterpolationInString = false;
       let didBreak = false;
+
       for (let i = 0; i < node.groups.length; ++i) {
         parts.push(printed[i]);
 
@@ -594,20 +595,20 @@ function genericPrint(path, options, print) {
         }
 
         // Ignore spaces before/after string interpolation (i.e. `"#{my-fn("_")}"`)
-        const isStartSCSSInterpolationInString =
-          iNode.type === "value-string" && iNode.value.startsWith("#{");
-        const isEndingSCSSInterpolationInString =
-          insideSCSSInterpolationInString &&
-          iNextNode.type === "value-string" &&
-          iNextNode.value.endsWith("}");
-
-        if (
-          isStartSCSSInterpolationInString ||
-          isEndingSCSSInterpolationInString
-        ) {
-          insideSCSSInterpolationInString = !insideSCSSInterpolationInString;
-
-          continue;
+        if (iNode.type === "value-string" && iNode.quoted) {
+          const positionOfOpeningInterpolation = iNode.value.lastIndexOf("#{");
+          const positionOfClosingInterpolation = iNode.value.lastIndexOf("}");
+          if (
+            positionOfOpeningInterpolation !== -1 &&
+            positionOfClosingInterpolation !== -1
+          ) {
+            insideSCSSInterpolationInString =
+              positionOfOpeningInterpolation > positionOfClosingInterpolation;
+          } else if (positionOfOpeningInterpolation !== -1) {
+            insideSCSSInterpolationInString = true;
+          } else if (positionOfClosingInterpolation !== -1) {
+            insideSCSSInterpolationInString = false;
+          }
         }
 
         if (insideSCSSInterpolationInString) {


Test patch:
diff --git a/tests/format/scss/map/function-argument/__snapshots__/jsfmt.spec.js.snap b/tests/format/scss/map/function-argument/__snapshots__/jsfmt.spec.js.snap
--- a/tests/format/scss/map/function-argument/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/format/scss/map/function-argument/__snapshots__/jsfmt.spec.js.snap
@@ -1,5 +1,56 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
+exports[`function-argument-2.scss format 1`] = `
+====================================options=====================================
+parsers: ["scss"]
+printWidth: 80
+                                                                                | printWidth
+=====================================input======================================
+$display-breakpoints: map-deep-merge(
+  (
+    "sm-only": "only screen and (min-width: #{$map-get + $grid-breakpoints + "hogehoge"}) and (max-width: #{$a})",
+    "sm-only": "inside a long long long long long long long long long long long long long long string #{call("")}",
+    "sm-only": "inside a long long long long long long long long long long long long long long string #{$foo} and #{call("")}",
+    "sm-only": "inside a long long long long long long long long long long long long long long string #{call($a)}",
+  ),
+  $display-breakpoints
+);
+
+@each $name, $hue in $hues {
+  $map: map.merge(
+    $map,
+    (
+      '#{$prefix}-#{$name}': blend.set($base, $hue: $hue),
+    )
+  );
+}
+
+=====================================output=====================================
+$display-breakpoints: map-deep-merge(
+  (
+    "sm-only": "only screen and (min-width: #{$map-get + $grid-breakpoints + "hogehoge"}) and (max-width: #{$a})",
+    "sm-only":
+      "inside a long long long long long long long long long long long long long long string #{call("")}",
+    "sm-only":
+      "inside a long long long long long long long long long long long long long long string #{$foo} and #{call("")}",
+    "sm-only":
+      "inside a long long long long long long long long long long long long long long string #{call($a)}",
+  ),
+  $display-breakpoints
+);
+
+@each $name, $hue in $hues {
+  $map: map.merge(
+    $map,
+    (
+      "#{$prefix}-#{$name}": blend.set($base, $hue: $hue),
+    )
+  );
+}
+
+================================================================================
+`;
+
 exports[`functional-argument.scss format 1`] = `
 ====================================options=====================================
 parsers: ["scss"]
diff --git a/tests/format/scss/map/function-argument/function-argument-2.scss b/tests/format/scss/map/function-argument/function-argument-2.scss
new file mode 100644
--- /dev/null
+++ b/tests/format/scss/map/function-argument/function-argument-2.scss
@@ -0,0 +1,18 @@
+$display-breakpoints: map-deep-merge(
+  (
+    "sm-only": "only screen and (min-width: #{$map-get + $grid-breakpoints + "hogehoge"}) and (max-width: #{$a})",
+    "sm-only": "inside a long long long long long long long long long long long long long long string #{call("")}",
+    "sm-only": "inside a long long long long long long long long long long long long long long string #{$foo} and #{call("")}",
+    "sm-only": "inside a long long long long long long long long long long long long long long string #{call($a)}",
+  ),
+  $display-breakpoints
+);
+
+@each $name, $hue in $hues {
+  $map: map.merge(
+    $map,
+    (
+      '#{$prefix}-#{$name}': blend.set($base, $hue: $hue),
+    )
+  );
+}