Better handling for Liquid Captures
Description
The Liquid {% capture %} tags are sometimes problematic. The current in-place logic for handling of captures is as follows:
- Captures can be skipped by add them to
ignoreTagList - If captures are not added to
ignoreTagListthen Æsthetic will attempt to reason with them.
The defect will occur when the inner contents of captures get creates. Based on code samples provided by @MaxDesignFR some time ago now, it seems that Æsthetic still has trouble in format execution. This is critical and needs to be patch before 4.0 of vscode-liquid.
Required Patches
Æsthetic should only handle \n newline structures contained with captures, unless capture exists within ignoreTagList. Preservation behaviour is priority here, for example:
Before Formatting
We are assuming capture does not exists within ignoreTagList.
<div>{% capture foo %}
hello {{ object.prop }}
{% if xxx %}
{{ something }} {% endif %}
{% endcapture %}</div>
After Formatting
Æsthetic should not touch or apply indentation and other rulesets within captures, only newlines. Based on the above sample, output should apply alignment only, for example:
<div>
{% capture foo %}
hello {{ object.prop }}
{% if xxx %}
{{ something }} {% endif %}
{% endcapture %}
</div>
A couple of takeaways here, firstly the <div>{% capture foo %} and {% endcapture %}</div> is forced. Secondly, indentation is applied respectively and all newline occurrences are indented but with whitespace is stripped. The dedentTagList[] Liquid formatting rule should be respected here in cases where a user wants alignment.
Capture is within DedentTagList
If the capture tag name happens to exists within dendentTagList then the default indentation should not be applied, this would result in the following:
<div>
{% capture foo %}
hello {{ object.prop }}
{% if xxx %}
{{ something }} {% endif %}
{% endcapture %}
</div>
Considerations
The above default handling might not be ideal in cases where the user wants to preserve whitespace, but this is the most logical approach in order to cater to the majority. More advanced code samples like that of MaxDesign need to respected. In situations of that nature, preservation will need to be defined within ignoreTagList[]. Adding capture to ignoreTagList or alternatively annotate with esthetic-ignore-next, for example (using the before formatting sample):
Using Capture in ignoreTagList
<div>
{% capture foo %}
hello {{ object.prop }}
{% if xxx %}
{{ something }} {% endif %}
{% endcapture %}
</div>
Notice here, we apply forcing to <div>{% capture foo %} and {% endcapture %}</div> but inner contents is preserved. This behaviour meets expectation but ensures structural intent.