diff --git a/changelog_unreleased/scss/19928.md b/changelog_unreleased/scss/19928.md new file mode 100644 index 000000000..dac033aba --- /dev/null +++ b/changelog_unreleased/scss/19928.md @@ -0,0 +1,13 @@ +#### Preserve trailing commas in single-item lists (#19928 by @kovsu) + + +```scss +// Input +$list: ("a",); + +// Prettier stable +$list: ("a"); + +// Prettier main +$list: ("a",); +``` diff --git a/src/language-css/print/parenthesized-value-group.js b/src/language-css/print/parenthesized-value-group.js index d97703359..05a6a8d0e 100644 --- a/src/language-css/print/parenthesized-value-group.js +++ b/src/language-css/print/parenthesized-value-group.js @@ -15,9 +15,10 @@ import { lineSuffixBoundary, softline, } from "../../document/index.js"; +import getNextNonSpaceNonCommentCharacter from "../../utilities/get-next-non-space-non-comment-character.js"; import isNextLineEmpty from "../../utilities/is-next-line-empty.js"; import isNonEmptyArray from "../../utilities/is-non-empty-array.js"; -import { locEnd, locStart } from "../loc.js"; +import { locEnd } from "../loc.js"; import { isConfigurationNode, isKeyInValuePairNode, @@ -28,18 +29,34 @@ import { } from "../utilities/index.js"; import { shouldPrintTrailingComma } from "./misc.js"; -function hasComma({ node, parent }, options) { - return Boolean( - node.source && - options.originalText - .slice(locStart(node), locStart(parent.close)) - .trimEnd() - .endsWith(","), +function hasTrailingComma({ node, parent }, options) { + if (parent.type !== "value-paren_group") { + return false; + } + + const nodes = node.type === "value-comma_group" ? node.groups : [node]; + const lastValue = nodes.findLast((child) => child.type !== "value-comment"); + + if (!lastValue) { + return false; + } + + const nextCharacter = getNextNonSpaceNonCommentCharacter( + options.originalText, + locEnd(lastValue), ); + return nextCharacter === ","; } function printTrailingComma(path, options) { - if (isVarFunctionNode(path.grandparent) && hasComma(path, options)) { + if ( + (isVarFunctionNode(path.grandparent) || + (options.parser === "scss" && + path.grandparent?.type !== "value-func" && + path.parent.groups.length === 1 && + !isKeyValuePairNode(path.parent.groups[0]))) && + hasTrailingComma(path, options) + ) { return ","; } diff --git a/tests/format/scss/trailing-comma/__snapshots__/format.test.js.snap b/tests/format/scss/trailing-comma/__snapshots__/format.test.js.snap index e213f217b..64bf0d2c7 100644 --- a/tests/format/scss/trailing-comma/__snapshots__/format.test.js.snap +++ b/tests/format/scss/trailing-comma/__snapshots__/format.test.js.snap @@ -179,7 +179,7 @@ $z-indexes: ( =====================================output===================================== .simplification { foo: ( - calc() // It is a comment + calc(), // It is a comment ); } @@ -230,7 +230,7 @@ $z-indexes: ( =====================================output===================================== .simplification { foo: ( - calc() // It is a comment + calc(), // It is a comment ); } @@ -288,6 +288,110 @@ a { ================================================================================ `; +exports[`issue-6356.scss - {"trailingComma":"es5"} format 1`] = ` +====================================options===================================== +parsers: ["scss"] +trailingComma: "es5" + printWidth: 80 (default) | +=====================================input====================================== +$single-string: ("a",); +$single-space-list: (1 2 3,); +$single-nested-list: ((1, 2),); +@include assert-equal(daff-string-split(".a", "."), ("a",)); + +$multiple-items: (1, 2,); +$single-argument: foo(1,); + +$single-entry-map: (a: 1,); + +$comment-after-comma: ("a", + // , +); +$comment-without-comma: ("a" + // , +); +$empty-comment-after-comma: ("a", + // +); + +=====================================output===================================== +$single-string: ("a",); +$single-space-list: (1 2 3,); +$single-nested-list: ((1, 2),); +@include assert-equal(daff-string-split(".a", "."), ("a",)); + +$multiple-items: (1, 2); +$single-argument: foo(1); + +$single-entry-map: ( + a: 1, +); + +$comment-after-comma: ( + "a", // , +); +$comment-without-comma: ( + "a" // , +); +$empty-comment-after-comma: ( + "a", // +); + +================================================================================ +`; + +exports[`issue-6356.scss - {"trailingComma":"none"} format 1`] = ` +====================================options===================================== +parsers: ["scss"] +trailingComma: "none" + printWidth: 80 (default) | +=====================================input====================================== +$single-string: ("a",); +$single-space-list: (1 2 3,); +$single-nested-list: ((1, 2),); +@include assert-equal(daff-string-split(".a", "."), ("a",)); + +$multiple-items: (1, 2,); +$single-argument: foo(1,); + +$single-entry-map: (a: 1,); + +$comment-after-comma: ("a", + // , +); +$comment-without-comma: ("a" + // , +); +$empty-comment-after-comma: ("a", + // +); + +=====================================output===================================== +$single-string: ("a",); +$single-space-list: (1 2 3,); +$single-nested-list: ((1, 2),); +@include assert-equal(daff-string-split(".a", "."), ("a",)); + +$multiple-items: (1, 2); +$single-argument: foo(1); + +$single-entry-map: ( + a: 1 +); + +$comment-after-comma: ( + "a", // , +); +$comment-without-comma: ( + "a" // , +); +$empty-comment-after-comma: ( + "a", // +); + +================================================================================ +`; + exports[`issue-6920.scss - {"trailingComma":"es5"} format 1`] = ` ====================================options===================================== parsers: ["scss"] @@ -387,7 +491,7 @@ $breakpoint-map: ( =====================================output===================================== $colors: hotpink deepskyblue firebrick; -$list: (a); +$list: (a,); $list: ("Helvetica", "Arial", sans-serif); $colors: ("red", "blue"); $config: ( @@ -492,7 +596,7 @@ $breakpoint-map: ( =====================================output===================================== $colors: hotpink deepskyblue firebrick; -$list: (a); +$list: (a,); $list: ("Helvetica", "Arial", sans-serif); $colors: ("red", "blue"); $config: ( diff --git a/tests/format/scss/trailing-comma/issue-6356.scss b/tests/format/scss/trailing-comma/issue-6356.scss new file mode 100644 index 000000000..d6d22eee8 --- /dev/null +++ b/tests/format/scss/trailing-comma/issue-6356.scss @@ -0,0 +1,19 @@ +$single-string: ("a",); +$single-space-list: (1 2 3,); +$single-nested-list: ((1, 2),); +@include assert-equal(daff-string-split(".a", "."), ("a",)); + +$multiple-items: (1, 2,); +$single-argument: foo(1,); + +$single-entry-map: (a: 1,); + +$comment-after-comma: ("a", + // , +); +$comment-without-comma: ("a" + // , +); +$empty-comment-after-comma: ("a", + // +);