puranjayjain / language-liquid

Liquid language support for Atom.
MIT License
28 stars 23 forks source link

Feature Request: Add auto-indentation support for HTML #15

Open fusion809 opened 8 years ago

fusion809 commented 8 years ago

Hi,

I have noticed that this package, when rendering HTML code, lacks the auto-indentation support of the language-html package. Is it possible for this feature to be added to this package too?

Thanks for your time, Brenton

puranjayjain commented 8 years ago

@fusion809 I think it is possible since the language-babel package auto indents jsx inside a scope when we cursor over any line which is incorrectly indented. See: https://github.com/gandm/language-babel#automatic-indenting-of-jsx

Do you want a behavior like that?

fusion809 commented 8 years ago

That is precisely what I had in mind. That would be excellent.

puranjayjain commented 8 years ago

I'll start work on it sometime this week. Along with a long pending scss issue. Also the settings could be exposed via the config api since we don't want another dot file.

panoply commented 7 years ago

+1 Would really love to see this feature!

sciascia commented 5 years ago

+1 if possible!

sciascia commented 5 years ago

I'm very new to the world of Atom and Regex but is there an easy way to modify this JS indentation definition and use it for Liquid?

'.source.js':
  'editor':
    'nonWordCharacters': '/\\()"\':,.;<>~!#@%^&*|+=[]{}`?-…'
    'commentStart': '// '
    'foldEndPattern': '^\\s*\\}|^\\s*\\]|^\\s*\\)'
    'increaseIndentPattern': '(?x)
        \\{ [^}"\']* $
      | \\[ [^\\]"\']* $
      | \\( [^)"\']* $
      '
    'decreaseIndentPattern': '(?x)
        ^ \\s* (\\s* /[*] .* [*]/ \\s*)* [}\\])]
      '

Have tried and failed miserably sorry (Regex breaks my brain sorry).

panoply commented 5 years ago

I've recently began exploring this issue with a VS Code extension that I maintain which provides liquid syntax support with VSC.

Indentation/beautification for the liquid language is not supported in any IDE from what I have seen and the only tool that does provide support and do a somewhat good job at indenting and formatting liquid is prettydiff but if you go the route of PrettyDiff you will run into errors or conflicts at some point because you become limited to the API PrettyDiff offers and its restrictive.

Liquid being a template language means it will almost be always used in conjunction with HTML thus providing support for this needs to be vigorously thought through. Developers apply liquid into HTML in unpredictable ways and you will often find attribute infusion, like <div {%- if foo -%}class="bar"{%- else -%}id="foo"{%- endif -%}> which is common practice but it complicates things because while you can skip indentation of the single line ternary statement consideration is required if a developer is formatting attributes multiline with third-party or your default IDE rest assured headaches will follow. This is one of many aspects that require consideration.

panoply commented 5 years ago

@puranjayjain I have managed to achieve beautification with liquid successfully using PrettyDiff in combination with JS-Beautify. There are still a few kinks to work out, but they seem to be very minor.

I managed to get this working by using a fairly new tool called https://unibeautify.com. In VS-Code users could choose to either rely on it as a dev dependency or you could include it as a dependency within this extension and deliver it users packaged in.

PrettyDiff is now at v3 (v100) and with it come a couple of fixes that helped with the Twig template language but this also indirectly helped with Liquid.

Maybe this will be of help to your project, below is the results of using UniBeautify:

Before Example:

<ul>
{%- for tag in collection.all_tags -%}
{% if current_tags contains tag %}
<li {% if condition %}
class="active"
{% endif %}>
{{ tag | link_to_remove_tag: tag }}
</li>
{% else %}
<li>
{{ tag | link_to_add_tag: tag }}
</li>
{% endif %}{%- endfor -%}
</ul>

After:

<ul>
  {%- for tag in collection.all_tags -%}
    {% if current_tags contains tag %}
      <li {% if condition %} class="active" {% endif %}>
        {{ tag | link_to_remove_tag: tag }}
      </li>
    {% else %}
      <li>
        {{ tag | link_to_add_tag: tag }}
      </li>
    {% endif %}
{%- endfor -%}
</ul>

.unibeautifyrc settings config:

{
  "Liquid": {
    "beautifiers": [
      "JS-Beautify", "Pretty Diff"
    ],
    "max_preserve_newlines": "1"
  },
  "JavaScript": {
    "beautifiers": ["Prettier", "Pretty Diff", "JS-Beautify", "ESLint"]
  },
  "JSON": {
    "beautifiers": ["Prettier", "Pretty Diff", "JS-Beautify"]
  },
  "TypeScript": {
    "beautifiers": ["Prettier", "Pretty Diff"]
  },
  "SCSS": {
    "beautifiers": [
      "Prettier", "Pretty Diff"
    ],
    "indent_size": "2"
  },
  "CSS": {
    "beautifiers": ["Prettier", "Pretty Diff", "JS-Beautify"]
  }
}
puranjayjain commented 5 years ago

@panoply We can probably add the above to the readme section as well for future reference

panoply commented 5 years ago

It's still a little buggy this solution and restrictive to those developers with coding style quirks. However, the good news is that I have dug deeper and now have created a working solution that runs PrettyDiff on HTML / Liquid code (enabling beautification) but the solution ignores <style> and <script> tags which allow developers to use ESLint on code within their <script> tag and a linter or Prettier on code within their <style> tags.

At this in point in time I have it working as a VS Code extension, it should be easy for you to create an Atom extension version from it. DO you want me to share the code with you?