diff --git a/.changeset/bright-ignore-range.md b/.changeset/bright-ignore-range.md new file mode 100644 index 000000000..cd7a30270 --- /dev/null +++ b/.changeset/bright-ignore-range.md @@ -0,0 +1,5 @@ +--- +'@shopify/prettier-plugin-liquid': minor +--- + +Add support for prettier-ignore-start / prettier-ignore-end range-based ignoring in Liquid templates diff --git a/packages/prettier-plugin-liquid/src/printer/utils/node.ts b/packages/prettier-plugin-liquid/src/printer/utils/node.ts index 42c723bc1..938e60cd9 100644 --- a/packages/prettier-plugin-liquid/src/printer/utils/node.ts +++ b/packages/prettier-plugin-liquid/src/printer/utils/node.ts @@ -156,7 +156,85 @@ export function isPrettierIgnoreNode( } export function hasPrettierIgnore(node: LiquidHtmlNode) { - return isPrettierIgnoreNode(node) || isPrettierIgnoreNode(node.prev); + return ( + isPrettierIgnoreNode(node) || + isPrettierIgnoreNode(node.prev) || + isPrettierIgnoreRangeStartNode(node) || + isPrettierIgnoreRangeEndNode(node) || + isInsidePrettierIgnoreRange(node) + ); +} + +export function isPrettierIgnoreRangeStartHtmlNode( + node: LiquidHtmlNode | undefined, +): node is HtmlComment { + return ( + !!node && + node.type === NodeTypes.HtmlComment && + /^\s*prettier-ignore-start(?=\s|$)/m.test(node.body) + ); +} + +export function isPrettierIgnoreRangeStartLiquidNode( + node: LiquidHtmlNode | undefined, +): node is LiquidTag { + return ( + !!node && + node.type === NodeTypes.LiquidTag && + node.name === '#' && + /^\s*prettier-ignore-start(?=\s|$)/m.test(node.markup) + ); +} + +export function isPrettierIgnoreRangeStartNode( + node: LiquidHtmlNode | undefined, +): node is HtmlComment | LiquidTag { + return isPrettierIgnoreRangeStartHtmlNode(node) || isPrettierIgnoreRangeStartLiquidNode(node); +} + +export function isPrettierIgnoreRangeEndHtmlNode( + node: LiquidHtmlNode | undefined, +): node is HtmlComment { + return ( + !!node && + node.type === NodeTypes.HtmlComment && + /^\s*prettier-ignore-end(?=\s|$)/m.test(node.body) + ); +} + +export function isPrettierIgnoreRangeEndLiquidNode( + node: LiquidHtmlNode | undefined, +): node is LiquidTag { + return ( + !!node && + node.type === NodeTypes.LiquidTag && + node.name === '#' && + /^\s*prettier-ignore-end(?=\s|$)/m.test(node.markup) + ); +} + +export function isPrettierIgnoreRangeEndNode( + node: LiquidHtmlNode | undefined, +): node is HtmlComment | LiquidTag { + return isPrettierIgnoreRangeEndHtmlNode(node) || isPrettierIgnoreRangeEndLiquidNode(node); +} + +/** + * Walk backward through siblings to determine if a node is inside an + * unmatched prettier-ignore-start / prettier-ignore-end range. + */ +export function isInsidePrettierIgnoreRange(node: LiquidHtmlNode): boolean { + let current = node.prev; + while (current) { + if (isPrettierIgnoreRangeEndNode(current)) { + return false; + } + if (isPrettierIgnoreRangeStartNode(current)) { + return true; + } + current = current.prev; + } + return false; } function getPrettierIgnoreAttributeCommentData(value: string): boolean { diff --git a/packages/prettier-plugin-liquid/src/test/prettier-ignore-range/fixed.liquid b/packages/prettier-plugin-liquid/src/test/prettier-ignore-range/fixed.liquid new file mode 100644 index 000000000..5b2ae7dac --- /dev/null +++ b/packages/prettier-plugin-liquid/src/test/prettier-ignore-range/fixed.liquid @@ -0,0 +1,41 @@ +It should preserve formatting inside html prettier-ignore-start / prettier-ignore-end range + +
{{ a | append: 'b' }}
+ +{{ a | append: 'b' }}
+ +It should handle multiple ignore ranges in the same parent +printWidth: 40 +{{ a | append: 'b' }}
+ +{{ a | append: 'b' }}
+ +{{ m | n: o }} + +{{ a | append: 'b' }}
+ +It should handle liquid comment ranges with multiple nodes +{% # prettier-ignore-start %} +{%capture foo%}{% for x in (0 .. 1) %}{% cycle a,b,c %}{% endfor %}{%endcapture%} +{{ a | append: 'b' }}
+ +{{ a | append: 'b' }}
+ +It should handle multiple ignore ranges in the same parent +printWidth: 40 +{{ a | append: 'b' }}
+ +{{ a | append: 'b' }}
+ +{{ m | n: o }} + +{{ a | append: 'b' }}
+ +It should handle liquid comment ranges with multiple nodes +{% # prettier-ignore-start %} +{%capture foo%}{% for x in (0 .. 1) %}{% cycle a,b,c %}{% endfor %}{%endcapture%} +