Repository: prettier/prettier (JavaScript)

Issue:
Unary minus must not be followed by a space in LESS
Current version of Prettier is adding a space after unary minus operator in LESS.

Config:
```
module.exports = {
    tabWidth: 4,
    overrides: [
        {
            files: ['*.less'],
            options: {
                parser: 'less',
            },
        },
    ],
};
```

Wrong autoformat:
```diff
 .xxx {
-    margin: 0 -(@arrowBorderWidth / 2) 0 0;
+    margin: 0 - (@arrowBorderWidth / 2) 0 0;
 }
```

I would expect no fix/added space.


Hints:
minimal playground repro link: https://prettier.io/playground/#N4Igxg9gdgLgprEAuEACAdAD264AdKVI1AWwEMAnAcwEsolUAGVAWgAoABSiiAdwCEIFACZwKAdRrCYAC1QB6VACYAlEyYBuAqgC+IADQgIABxg1oAZ2ShufAAqUEVlGQA2vMgE8rhgEYUyMABrOBgAZTISOAAZOjhkADM3Czg-AODQsONAuipkGAoAV1SQOBJfOGFRYWiyKCpCsio4ADEhchgzeuQQMkKYCAMQGRgSV3EZGngLbLA4MKcpmgA3Kc8esAsfEDoUihg7AKpyROSSgCsLTDDc1zgARUKIeFPXFMNsij2eu62h4wodBgkmkMmQAA5GB8eClxAFjD0AXA9st4oYAI5PeCHEzOXoWFhQOCVSpDChwTE0cmHJonJBJN4lFIkGj5IpM25wACCnUBvn6cDsYliRNe7xAFk5j2e8XpZ0MMDIvhBsmQSgVARorlyAGEICQ6aULABWIaFFIAFSVzgZ4uWxQAklBRLAwmBAaYuc6wjBPHcxXAdDogA
Please follow the [issue template](https://github.com/prettier/prettier/blob/main/.github/ISSUE_TEMPLATE/formatting.md?plain=1) in your first comment. Related to https://github.com/prettier/prettier/issues/12613 and https://github.com/prettier/prettier/issues/4698 (duplicate?)

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
@@ -744,6 +744,18 @@ function genericPrint(path, options, print) {
           continue;
         }
 
+        // No space before unary minus followed by an opening parenthesis `-(`
+        if (
+          (options.parser === "scss" || options.parser === "less") &&
+          isMathOperator &&
+          iNode.value === "-" &&
+          isParenGroupNode(iNextNode) &&
+          locEnd(iNode) === locStart(iNextNode.open) &&
+          iNextNode.open.value === "("
+        ) {
+          continue;
+        }
+
         // Add `hardline` after inline comment (i.e. `// comment\n foo: bar;`)
         if (isInlineValueCommentNode(iNode)) {
           if (parentNode.type === "value-paren_group") {


Test patch:
diff --git a/tests/format/less/parens/__snapshots__/jsfmt.spec.js.snap b/tests/format/less/parens/__snapshots__/jsfmt.spec.js.snap
--- a/tests/format/less/parens/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/format/less/parens/__snapshots__/jsfmt.spec.js.snap
@@ -302,6 +302,23 @@ a {
     unicode-range: U+0025-00FF, U+4??; /* multiple values */
 }
 
+// no space after unary minus when followed by opening parenthesis, #13998
+.unary_minus_single {
+  margin: -(@a);
+}
+
+.unary_minus_multi_1 {
+  margin: 0 -(@a);
+}
+
+.unary_minus_multi_2 {
+  margin: 0  -( @a + @b );
+}
+
+.binary_minus {
+  margin: 0 - (@a);
+}
+
 =====================================output=====================================
 a {
   prop1: func(1px, 1px, 1px, func(1px, 1px, 1px, func(1px, 1px, 1px)));
@@ -365,7 +382,7 @@ a {
   background: element(#css-source);
   padding-top: var(--paddingC);
   margin: 1 * 1 (1) * 1 1 * (1) (1) * (1);
-  prop: -1 * -1 - (-1) * -1 -1 * -(-1) - (-1) * -(-1);
+  prop: -1 * -1 -(-1) * -1 -1 * -(-1) -(-1) * -(-1);
   prop4: +1;
   prop5: -1;
   prop6: word + 1; /* word1 */
@@ -396,7 +413,7 @@ a {
   prop41: --(1);
   prop42: 1px+1px+1px+1px;
   prop43: 1px + 1px + 1px + 1px;
-  prop44: -1+-1 - (-1)+-1 -1+-(-1) - (-1)+-(-1);
+  prop44: -1+-1 -(-1)+-1 -1+-(-1) -(-1)+-(-1);
   prop45: round(1.5) * 2 round(1.5) * 2 round(1.5) * 2 round(1.5) * 2;
   prop46: 2 * round(1.5) 2 * round(1.5) 2 * round(1.5) 2 * round(1.5);
   prop47: (round(1.5) * 2) (round(1.5) * 2) (round(1.5) * 2) (round(1.5) * 2);
@@ -472,5 +489,22 @@ a {
   unicode-range: U+0025-00FF, U+4??; /* multiple values */
 }
 
+// no space after unary minus when followed by opening parenthesis, #13998
+.unary_minus_single {
+  margin: -(@a);
+}
+
+.unary_minus_multi_1 {
+  margin: 0 -(@a);
+}
+
+.unary_minus_multi_2 {
+  margin: 0 -(@a + @b);
+}
+
+.binary_minus {
+  margin: 0 - (@a);
+}
+
 ================================================================================
 `;
diff --git a/tests/format/less/parens/parens.less b/tests/format/less/parens/parens.less
--- a/tests/format/less/parens/parens.less
+++ b/tests/format/less/parens/parens.less
@@ -259,3 +259,20 @@ a {
     unicode-range: U+4??;              /* wildcard range */
     unicode-range: U+0025-00FF, U+4??; /* multiple values */
 }
+
+// no space after unary minus when followed by opening parenthesis, #13998
+.unary_minus_single {
+  margin: -(@a);
+}
+
+.unary_minus_multi_1 {
+  margin: 0 -(@a);
+}
+
+.unary_minus_multi_2 {
+  margin: 0  -( @a + @b );
+}
+
+.binary_minus {
+  margin: 0 - (@a);
+}
diff --git a/tests/format/scss/parens/__snapshots__/jsfmt.spec.js.snap b/tests/format/scss/parens/__snapshots__/jsfmt.spec.js.snap
--- a/tests/format/scss/parens/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/format/scss/parens/__snapshots__/jsfmt.spec.js.snap
@@ -418,10 +418,10 @@ a {
   );
   padding-top: var(--paddingC);
   margin: 1 * 1 (1) * 1 1 * (1) (1) * (1);
-  prop: -1 * -1 - (-1) * -1 -1 * -(-1) - (-1) * -(-1);
+  prop: -1 * -1 -(-1) * -1 -1 * -(-1) -(-1) * -(-1);
   prop1: #{($m) * (10)};
   prop2: #{$m * 10};
-  prop3: #{- (-$m) * -(-10)};
+  prop3: #{-(-$m) * -(-10)};
   prop4: +1;
   prop5: -1;
   prop6: word + 1; /* word1 */
@@ -469,7 +469,7 @@ a {
   prop41: --(1);
   prop42: 1px+1px+1px+1px;
   prop43: 1px + 1px + 1px + 1px;
-  prop44: -1+-1 - (-1)+-1 -1+-(-1) - (-1)+-(-1);
+  prop44: -1+-1 -(-1)+-1 -1+-(-1) -(-1)+-(-1);
   prop45: round(1.5) * 2 round(1.5) * 2 round(1.5) * 2 round(1.5) * 2;
   prop46: 2 * round(1.5) 2 * round(1.5) 2 * round(1.5) 2 * round(1.5);
   prop47: (round(1.5) * 2) (round(1.5) * 2) (round(1.5) * 2) (round(1.5) * 2);