Po niekoľkých hodinách strávených snahou prinútiť zreťazené metódy v PHP zoradiť sa pekne pod seba, som napokon našiel riešenie. Inými slovami, pri uložení súboru som chcel prejsť z tohto:
$this->user->account->organizations()->saveMany(Organization::factory(5)
->make())->first()->update(['name' => 'A Big Brand Name']);
Na niečo, čo vyzerá takto:
$this->user->account
->organizations()
->saveMany(Organization::factory(5)->make())
->first()
->update(['name' => 'A Big Brand Name']);
Druhá verzia je jednoznačne čitateľnejšia, a teda trvá kratšie pochopiť, čo kód robí.
Čo mi nefungovalo #
Tu je niekoľko rôznych, možno nesúvisiacich metód na riešenie tohto problému, ktoré mi nefungovali, v náhodnom poradí.
coc-prettier #
Vo svojom aktuálnom nastavení neovim používam coc-prettier, najmä pre jeho jednoduchosť pri práci s Markdownom (prose-wrap, že?) a JavaScriptom. PHP však prettier nepodporuje natívne a je dostupný ako komunitný plugin prettier/plugin-php.
Momentálne to vyzerá tak, že
tieto dva spolu nevychádzajú.
Odpoveď je celkom čerstvá a určite existuje potenciál pre prettier pluginy
v rámci coc-prettier, no žiaľ, viac som na túto tému nenašiel.
Intelephense v coc-phpls s coc-prettier #
Spolu s coc-prettier dokáže
coc-phpls tiež formátovať PHP pri
uložení, a to pomocou týchto dvoch relevantných nastavení v :CocConfig:
"intelephense.format.enable": true,
"coc.preferences.formatOnSaveFiletypes": ["php"]
Žiaľ, v čase písania je jedinou konfiguračnou možnosťou formátovača
intelephense.format.braces. Toto nastavenie nemá žiadny vplyv na
zarovnávanie zreťazených PHP metód. Navyše sa akosi dostáva do konfliktu s
tabWidth z prettiera, ak sa napevno zakódovaná hodnota Intelephense líši.
Nakoniec som obe vyššie uvedené nastavenia odstranil/vypol.
vim-phpfmt #
S pluginom vim-phpfmt som mal čo sa týka zarovnávania zreťazených metód v PHP absolútnu smolu. Čakalo sa to, keďže plugin nebol aktualizovaný viac ako 5 rokov.
Využíva phpcbf, čiže PHP Code Beautifier and Fixer z balíka
PHP CodeSniffer, ktorý je
aktívne vyvíjaný. Verím, že tento prístup by mohol fungovať, no nie som si
istý, ako dlho by trvalo, kým by to celé nachodilo.
inotifywait skript #
V jednom momente som skúšal využiť skript na sledovanie testov tak, že som na zmenený súbor spustil globálne nainštalovaný prettier, keďže som ho mal aj tak spustený:
#!/bin/bash
while true; do
FILE=$(inotifywait --recursive \
--exclude=".*.*sw*" --exclude="4913" \
./watch_this_folder --format "%w%f" -e close_write)
&& clear
&& prettier --parser=php -w "$FILE"
done
Mal som však s týmto prístupom množstvo problémov - od oneskorených testov, cez to, že vim neprekreslil reformatovaný súbor, až po náhodné formátovanie súborov alebo aj celých priečinkov, takže som touto cestou nešiel ďalej.
Čo funguje #
Našiel som dve riešenia, ktoré pre zarovnávanie zreťazených metód v PHP fungujú rozumne dobre. Obe sa opierajú o prettier.
prettier/plugin-php vimscript #
Upravený vimscript, o ktorom som písal včera fungoval a myslel som si, že pri ňom zostanem. Choďte sa pozrieť tam na viac podrobností o tomto prístupe.
vim-prettier #
S komplikovaným riešením uvedeným v #119 pre vim-prettier, ktoré je momentálne odkazované v dokumentácii, som nemal šťastie. Tiež mi prišlo čudné mať nainštalovaný ako vim plugin súčasne vim-prettier aj coc-prettier.
Keď som to však všetko dokumentoval, náhodou som objavil poklad v #263. Pokiaľ viem, riešenie vyžaduje len pár krokov. Nainštalujte plugin-php ako závislosť projektu:
npm install -D @prettier/plugin-php
Potom upravte súbor vimrc:
call plug#begin('~/.vim/plugged')
Plug 'prettier/vim-prettier', { 'do': 'npm install', 'for': ['php'] }
call plug#end()
autocmd BufWritePre *.php PrettierAsync
Spustite :PlugInstall a môžete ísť. Ako vidíme, vim-prettier je
povolený len pre PHP súbory, ostatné rieši coc-prettier v mojom
nastavení. Keď som videl, že tieto dva naozaj fungujú vedľa seba bez
problémov, bol som s týmto nastavením spokojnejší a moja neochota ustúpila.
Na tomto nastavení sa mi naozaj páči jeho jednoduchosť a tiež to, že
rešpektuje projektový súbor .prettierrc, presne podľa môjho vkusu,
napríklad:
{
"tabWidth": 4,
"semi": false,
"singleQuote": true,
"trailingComma": "es5",
"trailingCommaPHP": true,
"proseWrap": "always",
"arrowParens": "avoid",
"bracketSpacing": true,
"phpVersion": "8.0",
"braceStyle": "1tbs"
}
Štandardné možnosti prettiera aj tie z
konfigurácie plugin-php
pekne na jednom mieste. Nevýhodou je, že ak chcete rôznu hodnotu tabWidth
pre rôzne typy súborov v rámci projektu, týmto spôsobom to presne nejde. No
tak by to trochu odporovalo filozofii prettiera, ktorý je zámerene
jednoznačný a konzistentný.
Žeľ, že som toto riešenie nenašiel hneď na začiatku - no lepšie neskôr ako nikdy. Príjemné písanie!