Skip to content

Keep multiline Blade directive arguments stable across runs - #477

Merged
nunomaduro merged 1 commit into
laravel:mainfrom
lazerg:fix/476-directive-argument-reindentation
Aug 5, 2026
Merged

Keep multiline Blade directive arguments stable across runs#477
nunomaduro merged 1 commit into
laravel:mainfrom
lazerg:fix/476-directive-argument-reindentation

Conversation

@lazerg

@lazerg lazerg commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

When the Blade formatter reformats a directive argument, it re-indents the continuation lines to the directive's column, but it never removes the indentation the previous run put there. With a ruleset that includes array_indentation this goes unnoticed, since php-cs-fixer collapses the argument back to column zero first. With a Blade-only setup ("preset": "empty" plus Pint/laravel_blade) no fixer does that, so every run pushes a nested @class([...]) or @include(..., [...]) another level to the right and pint --test never passes.

This strips the directive's own indentation from the argument before formatting it, so re-indenting afterwards puts the lines back where they were instead of stacking on top.

Fixes #476

@nunomaduro
nunomaduro merged commit 862096b into laravel:main Aug 5, 2026
11 checks passed
@Dimimo

Dimimo commented Aug 9, 2026

Copy link
Copy Markdown

@lazerg
Your commit fixed 3 of the 4 files experiencing accumulated indentation. One file still shows a strange behavior. It 'loops' around when running pint 4 times. Before the first run (the way it should look like):

            <div @class([
                    'inline-block',
                    'border-b-2',
                    'border-gray-700',
                    'bg-green-100' => $customer->paid,
                    'bg-red-100' => !$customer->paid,
                    'p-2',
                    'text-right',
                    'align-top',
                    'text-lg',
                ])>
                Has it been paid yet?
            </div>

Second run:

            <div @class([
            'inline-block',
            'border-b-2',
            'border-gray-700',
            'bg-green-100' => $customer->paid,
            'bg-red-100' => !$customer->paid,
            'p-2',
            'text-right',
            'align-top',
            'text-lg',
                    ])>
                Has it been paid yet?
            </div>

Tirth run:

            <div @class([
                'inline-block',
                'border-b-2',
                'border-gray-700',
                'bg-green-100' => $customer->paid,
                'bg-red-100' => !$customer->paid,
                'p-2',
                'text-right',
                'align-top',
                'text-lg',
            ])>
                Has it been paid yet?
            </div>

the 4th run puts the block back where it should be.

The .prettierrc settings:

{
    "printWidth": 100,
    "semi": true,
    "singleQuote": true,
    "tabWidth": 4,
    "trailingComma": "all",
    "bracketSpacing": false,
    "bracketSameLine": false,
    "plugins": ["prettier-plugin-blade", "prettier-plugin-tailwindcss"],
    "tailwindConfig": "tailwind.config.js",
    "overrides": [
        {
            "files": [
                "*.blade.php"
            ],
            "options": {
                "parser": "blade"
            }
        }
    ]
}

I tried to override the blade file options with

        "options": {
                "parser": "blade",
                "bladeBlankLinesAroundDirectives": "preserve",
                "bladeDirectiveArgSpacingOverrides": ["if", "elseif", "unless", "while", "for", "foreach", "forelse", "switch", "case", "class"] 
        }

Adding 'class' to the default settings. But alas... For now I just rollback that one file.

Anyway, your commit fixed the other anomalities for which my thanks 🏆

@lazerg

lazerg commented Aug 9, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for testing it. I could reproduce this one, and it turned out to be a different bug. Prettier wraps the @class onto its own line, and the step that pulls it back onto the tag line then dedents the array body by four spaces. With no indentation fixer in your ruleset nothing pulls it back, so the file cycles instead of settling. Fix in #479.

One thing on the config: Pint does not read your .prettierrc. It runs its own bundled Prettier with its own options, so bladeDirectiveArgSpacingOverrides and friends there have no effect on it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Pint/laravel_blade] Multiline Blade directive arguments are re-indented on every run

3 participants