Twig-CS-Fixer icon indicating copy to clipboard operation
Twig-CS-Fixer copied to clipboard

Indentation in hash parameters

Open lukepass opened this issue 1 year ago • 4 comments

Expected behavior

I wish that hash arguments were indented when on multiple lines. For example:

From:

{{ form_start(form, {
                    attr: {
                    class: 'quiz',
                    'data-controller': 'ajax-form quiz',
                    'data-ajax-form-targets-value': ['#ajax-content-1', '#ajax-content-2', '#lesson-footer']|serialize('json') ,
    'data-ajax-form-spinner-html-value': include('shared/_spinner.html.twig'),
    'data-ajax-form-scroll-to-value': '#ajax-content-1',
}
}) }}

To:

{{ form_start(form, {
    attr: {
        class: 'quiz',
        'data-controller': 'ajax-form quiz',
        'data-ajax-form-targets-value': ['#ajax-content-1', '#ajax-content-2', '#lesson-footer']|serialize('json') ,
        'data-ajax-form-spinner-html-value': include('shared/_spinner.html.twig'),
        'data-ajax-form-scroll-to-value': '#ajax-content-1',
    }
}) }}

Actual behavior

Hash indentation is not changed.

lukepass avatar Jul 02 '24 08:07 lukepass

Hi, do you want to try working on a rule ?

VincentLanglet avatar Jul 02 '24 08:07 VincentLanglet

Yes, of course! I would like to! How can I do that?

lukepass avatar Jul 02 '24 09:07 lukepass

You can play with https://github.com/VincentLanglet/Twig-CS-Fixer/blob/main/tests/Token/Tokenizer/TokenizerTest.php to understand how the code is Tokenized.

For example {{ {'foo': 42} }} is tokenized with tokens of the type

  • Token::VAR_START_TYPE
  • Token::WHITESPACE_TYPE
  • Token::PUNCTUATION_TYPE {
  • Token::STRING_TYPE (Be aware that without the quote it's a Token::NAME_TYPE)
  • Token::PUNCTUATION_TYPE :
  • Token::WHITESPACE_TYPE
  • Token::NUMBER_TYPE
  • Token::PUNCTUATION_TYPE }
  • Token::WHITESPACE_TYPE
  • Token::VAR_END_TYPE

Notice that in case of the token } you'll have $token->getRelatedToken() returning the one which is opening {. (This is currently used only for ternary $a ? $b : $c here https://github.com/VincentLanglet/Twig-CS-Fixer/blob/1f1bcc5b7a608c64603e8d3a879508316bfc9919/src/Rules/Operator/OperatorSpacingRule.php#L35-L37).

You rule will need to be configurable to know what should be used for indent (tab or space ? And how many space ?) an example can be found here https://github.com/VincentLanglet/Twig-CS-Fixer/blob/main/src/Rules/Whitespace/IndentRule.php#L14

Here you have an example of rule which works on ), } and ] https://github.com/VincentLanglet/Twig-CS-Fixer/blob/1f1bcc5b7a608c64603e8d3a879508316bfc9919/src/Rules/Punctuation/TrailingCommaMultiLineRule.php#L31 ; I assume you'll have to

  • Create a rule on }
  • get the related token {
  • Compute the indentation of the {
  • Get every line with a hash
  • Compare reindent the lines.

But the issue you'll encounter will be

  • Case like {} inside another {} since the indentation will be different
  • And worst, hash with multilines like
{{ form_start(form, {
foo: 42
    + 42
}
}) }}

because people might expect it to be fixed to

{{ form_start(form, {
    foo: 42
         + 42
}
}) }}

My fear is the fact that putting one step in the indentation rule will end with having to indenting everything ({, (, operator, ...) which seems kinda complicated (PHP-Cs-Fixer rule is not even perfect ATM).

VincentLanglet avatar Jul 02 '24 09:07 VincentLanglet

@lukepass Just wanted to say that I'm also very much interested in having this properly formatted. So thanks in advance for your work on this 🙌 💪

ruudk avatar Jul 03 '24 10:07 ruudk

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

github-actions[bot] avatar Dec 31 '24 01:12 github-actions[bot]