Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

When I open a PHP file, Neovim sets nosmartindent and indentexpr=GetPhpIndent() .

This is a bummer, because GetPhpIndent() is completely broken and makes the editing experience a nightmare where I have to constantly fix the indentation of every line I type.

I created a file $RUNTIME/after/ftplugin/php.lua with this content inside:

vim.bo.indentexpr = nil
vim.bo.smartindent = true
print("I APPLIED SOME SETTINGS!")

I added the print statement just to confirm it gets loaded, and it does. Every time I open my PHP file, I see the text printed.

HOWEVER, my settings are unchanged. The settings are still being set by the runtime:

So it it because my lua file doesn't work? NOPE, if I source it after opening the file, my settings are updated correctly.

So it seems like Nvim's default settings are applied after my ftplugin file, in which case what the heck is the point of ftplugin?

Help!

Indent scripts are sourced after all filetype plugins, including those in after/, and syntax scripts are sourced after all indent scripts, including those in after/.

In other words, the sourcing order is not "per-location":

" first wave: root of user runtime
ftplugin/foo.vim
indent/foo.vim
syntax/foo.vim
" second wave: Vim runtime
$VIMRUNTIME/ftplugin/foo.vim
$VIMRUNTIME/indent/foo.vim
$VIMRUNTIME/syntax/foo.vim
" third wave: after in user runtime
after/ftplugin/foo.vim
after/indent/foo.vim
after/syntax/foo.vim

but "per-function":

" first wave: filetype plugins
ftplugin/foo.vim
$VIMRUNTIME/ftplugin/foo.vim
after/ftplugin/foo.vim
" second wave: indent scripts
indent/foo.vim
$VIMRUNTIME/indent/foo.vim
after/indent/foo.vim
" third wave: syntax scripts
syntax/foo.vim
$VIMRUNTIME/syntax/foo.vim
after/syntax/foo.vim

So your settings from the first wave (ftplugin) are overridden by the second wave (indent).

Since the settings you are trying to override come from an indent script, you must put your overrides in after/indent/php.vim.

what the heck is the point of ftplugin?

  • The point of indent scripts is to deal with filetype-specific indenting matters.
  • The point of syntax scripts is to deal with filetype-specific syntax highlighting matters.
  • The point of filetype plugins is to deal with everything else filetype-specific.
  • Huh, that's weird... Why is config loading split into separate waves like that? Is there a practical reason or just legacy reasons? In any case, that perfectly explains my problem, thanks a lot! – Hubro Nov 29, 2022 at 15:28

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.