1

I've recently been organizing my vimrc and putting mappings into vimfiles/plugin and vimfiles/ftplugin files (not to mention abbs, functions and commands).

However, these scripts are sourced before default scripts (See :h rtp & :help ftplugin-overrule) and any e.g. mappings can get clobbered by default mappings.

The latter help's only viable suggestion is to put these files into the vimfiles/after dir. But given that there's no way of knowing without checking all default scripts for mapping etc that might overwrite user mappings etc, it would seem that the user's plugin, ftplugin dir are useless. And that I need to put everything into the after dir. Any maps etc put in these user's dirs just might be unexpectedly overwritten by default scripts.

For example, I have vimfiles/ftplugin/html.vim with mapping <C-b>. This is overwritten by default html.vim. If I put latter mapping in vimrc it too is overwritten.

If I have a mapping in vimfiles/mapping.vim that is the same as any of the default scripts later sourced it is overwritten.

Am I showing ignorance of something here? I'm tempted to change the runtimepath to put my scripts after default scripts. But maybe there's a good reason that, say, default html.vim script is sourced after (is more important than) my html.vim?

3
  • 1
    I cannot find a mapping for <C-B> in html.vim - or anywhere else in $VIMRUNTIME. Can you specify your Vim version and the exact location of these mappings? Maybe you will find :help ftplugin, especially the section titled DISABLING, helpful.
    – Friedrich
    Feb 25 at 7:49
  • Anecdotally I use (in addition to vimrc) ~/.vim/after for all filetype stuff (syntax, indent, ftplugin) to customize anything coming from defaults, plugins, etc. For compiler scripts, colorschemes, ftdetect, etc., I use ~/.vim. And I use ~/.vim/vimrc
    – D. Ben Knoble
    Feb 25 at 14:49
  • 1
    I should mention that it would be an anti-pattern for a Plugin (in the sense of something you distribute to others via, say, Git) to use after directories unless it absolutely had to.
    – D. Ben Knoble
    Feb 25 at 14:51

3 Answers 3

5

The reason that the user ftplugin is sourced early is so you can entirely replace the runtime's file with your own. In order to do so, you need to set the b:did_ftplugin in your copy to prevent the runtime's ftplugin being loaded.

If you look at the top of $VIMRUNTIME/ftplugin/html.vim, you'll see the lines:

if exists("b:did_ftplugin")
  finish
endif
let b:did_ftplugin = 1

This means that if you set b:did_ftplugin in ~/.vim/ftplugin/html.vim the runtime's file will exit immediately.

The purpose of the after directory is if you do want some of its settings and just want to override some of these or add some of your own.

For the documentation on this, see the Note in item 1 of :help ftplugin-overrule, and items 2 and 3. (You can ignore the stuff about making a copy of Vim's file: it's only the setting of b:did_ftplugin that determines whether or not the runtime file will be loaded.)

2

When you speak of mappings being overridden, and even of putting mappings either in the vimrc or in ftplugin files, I'm wondering something. I'll address this doubt, to be sure.

Are the mappings you store in your ftplugin files defined as buffer-local? Everything that goes into ftplugin files shall be buffer-local (except for functions, but functions should go into autoload plugin files). This means:

  • mappings and abbreviations are annotated with <buffer>
  • commands need the -b parameter
  • menus require plugin support
  • variables shall belong to b: namespace/scope
  • vim options shall be local-options set with :setlocal

Anything else that smells global doesn't belong to ftplugin files. And nothing local can be set in the vimrc or in other plugin/autoload plugin files without passing through an autocommand.


Also, I have plenty ftplugins files. None of them being in the after directory, and none of them setting b:did_ftplugin. That's because they define stuff that are unlikely to conflict with default ftplugin files.

This also leaves room for users of my plugins to put things in the after directory to adjust settings, or in their own ~/.vim/ftplugin directory to prevent my scripts from being loaded.


Anyway, I confirm what other have said.

  • Either put your mappings in the after directory
  • Or set b:did_ftplugin to prevent standard/default ftplugin files from being loaded -- but then, nothing from them will be set.

And don't forget: everything that goes into ftplugin files shall be buffer-local.

0

The solution for such problems is indeed the after version of these script.

e.g:~/vimfiles/after/ftplugin/html.vim

If you want to override the default you have to put you settings in after.

I would not say ~/vimfiles/ftplugin is useless in general. Vim use a generic runtime path system and executes the scripts of ftplugin in the order of the runtime path and then the script of after/ftplugin in the same runtime path order.

4
  • How can I ever be sure that what I put in vimfiles/plugin or ftplugin will not be overwritten by defaults? And I would've thought that user files would take precedence over defaults.
    – Tom
    Feb 25 at 7:03
  • If you put it in vimfiles/ftplugin/ they will be overridden but if you put it in vimfiles/after/ftplugin they will not since the default has no after. The propose of after is precisely to give the user the possibility to override the standard (aka default). Feb 25 at 7:07
  • Apologies if I'm being irritatingly persistent but, what's the point of the vimfiles/ftplugin and 'vimfiles/plugin` folders if one can never be sure they'll not be overwritten by defaults.
    – Tom
    Feb 25 at 7:12
  • No problem your question is very valid. It is my answer that is not clear enough. The way Vim is coded is very generic and rooted in the history of Vim. All the folder in runtimepath can have the same structure with the various subfolders plugin, ftplugin, after\ftplugin, ... and they are visited in the order of the runtimepath order for each category (generic code). It is up to the user to use it they way they want. In particular it is indeed a common practice in the vimfiles entry to not use the ftplugin entries and to only use the after/ftplugin entries Feb 25 at 10:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.