Please explain Vim's configuration directories hierarchy - vim

I am trying to update my Vim configuration scripts. There are a number of sub-directories in my ~/.vim directory and I'm not sure the specifics of what they do, nor why there are some that seem to be redundant.
Here is what my ~/.vim directory tree looks like
|-after
|---ftplugin
|---syntax
|-autoload
|-compiler
|-doc
|-ftplugin
|---latex-suite
|-----dictionaries
|-----macros
|-----packages
|-----templates
|---python
|-indent
|-plugin
|-spell
|-syntax
Now for the specific questions.
What goes in plugin vs ftplugin?
What is the difference between plugin and autoload?
When should I put something in after/... instead of in the directories directly under ~/.vim?

Whatever goes into plugin is loaded whenever vim starts whereas what you put in ftplugin is only loaded for the specific filetype it corresponds to (so if you have a folder there called python all the files there will be loaded when you open a python file.
In autoload you should have the functions corresponding to the the scripts defined in plugin. The functions here will only be loaded when called by the first time.
In after you should put settings that you want to change from the normal plugin loading.
As an example suppose you like the settings that some plugin for latex gives you, but it redefined a mapping that you had in your .vimrc. You can revert this with autocommands or by putting the correct definitions in after.

I think this would explain exactly what each folder does: http://learnvimscriptthehardway.stevelosh.com/chapters/42.html
Also might want to check :h runtimepath.
Hope this helps. :)

All those directories are part of the runtimepath. Try :h runtimepath and it will link you to your answers:
Check :h write-plugin
Check :h autoload-functions
after/... scripts are executed last, so they can override settings of earlier scripts. You can read more about this in :h runtimepath.

Related

How to set a VimScript to be executed last?

Problem
A setting in my vimrc (set noshowmode) is being overridden by a plugin later in the loading process.
Goal
Have a VimScript file be executed last (or at least after plugins).
What I Know
Plugin VimScripts are executed after the vimrc (Source).
The after-directory is run close to last and holds user overrides
(Source: :h after-directory).
Vim's runtimepath determines the order of what is run.
Failed Attempts
I tried appending a VimScript file (containing set noshowmode) to the
end of $VIMRUNTIME with
set runtimepath=$VIMRUNTIME,~/.vim/nosmd.vim, but this method ended up
messing up other plugins (namely vim-airline, which did not load).
I also tried creating the ~/.vim/after directory and putting my
VimScript in there, but this had no effect.
Your attempts
set runtimepath=$VIMRUNTIME,~/.vim/nosmd.vim
That cannot work. 'runtimepath' contains a list of root configuration directories; you cannot directly place script files in there. Instead, point to a directory that contains plugin/yours.vim.
I also tried creating the ~/.vim/after directory and putting my VimScript in there, but this had no effect.
You can check with :scriptnames to see whether your script was executed (and at the end of the plugin load sequence!)
Solutions
An ounce of prevention is better than any workaround. I would first try to locate the culprit who changes the 'showmode' option; a plugin shouldn't do this (or at least have a configurable option to disable it).
:verbose set showmode?
might already tell you who changed this setting.
As #romainl already commented, ~/.vim/after/plugin/myplugin.vim should work for undoing this. If it doesn't try the following autocmd (in your ~/.vimrc) as a last resort:
autocmd VimEnter * set noshowmode

How to load a vimscript file after loading plugin utl.vim?

I need to source some configuration lines after loading a plugin called [utl.vim][1].
The documentation says, I need to put these configurations into after-directory:
[23] NOte that you cannot include this line in your .vimrc because it is
:source'd before utl_rc.vim (which defines g:utl_cfg_hdl_mt_generic).
So either include/change it at <url:config:#r=utl_cfg_hdl_mt_text_directory>
or include it in the after-directory, see <url:vimhelp:after-directory#5.>
I created a file called utl.vim inside ~/.vim/after/ directory.
But this file is not sourced. I verified this using :scriptnames.
How to assure that Vim sources this file after loading utl.vim plugin?
The list of files/directories loaded by Vim is described at :help startup. Despite it lists the plugin directories, it doesn't mentions the after directory, so what you are seeing is the expected behavior.
Usually the after directory is source for filetype plugins, as explained in Vim FAQ 26.3 - "How do I extend an existing filetype plugin?". It is possible that the plugin will run something like :runtime! after/**/*.vim, but if the documentation is unclear will should ask to the plugin author, because it would be probably easier for users to be allowed to set this variable, and them the plugin could append/prepend default values to it

vim, pathogen, and load order of ftplugin files

I've been using Vim and pathogen for a while, and things were working fine, but recently I've started having load order issues with my ftplugin configuration.
The specific problem I'm having right now is that python-mode is overriding my ftplugin settings. I've got a ~/.vim/ftplugin/python.vim that contains the following line:
setlocal textwidth=119
python-mode comes with its own ftplugin file, which also sets textwidth, in ~/.vim/bundle/python-mode/ftplugin/python/pymode.vim.
The problem is that Vim is now loading python-mode's ftplugin file after my ftplugin file, so I'm ending up with its textwidth=79. I recently had to reinstall MacPorts, and I think something must have changed in the stock configuration.
I've tried various tricks involving turning filetype/plugin detection off before invoking pathogen, per various other answers, but none of them are helping.
Through the use of verbose set textwidth? and some echomsg debugging, I know that both ftplugin files are being invoked, and that they're being invoked in the wrong (for my needs) order.
Is there any way to force Vim/pathogen to invoke my ftplugin files after those of the plugins?
I've even tried putting my settings into ~/.vim/after/plugin/pymode.vim, but that's loaded immediately after pathogen sets up the plugin, so it still runs before ftplugin files, which only get loaded once I edit a Python file.
It turns out that maybe this never worked the way I thought. I didn't realize that Vim also supported ~/.vim/after/ftplugin, so I was able to move my overrides to ~/.vim/after/ftplugin/python.vim and get the behavior I was expecting. I'm loath to answer my own questions on SO, but hopefully this will help someone else.
Plain Vim loads the plugin scripts in alphabetical order. This is from :help load-plugins
... all directories in the 'runtimepath' option will be
searched for the "plugin" sub-directory and all files ending in ".vim"
will be sourced (in alphabetical order per directory), also in
subdirectories.
So you can set plugin loading order by renaming <filetype>_plugin.vim to <filetype>/35plugin.vim. 35 is your desired loading order. I think this should work with Pathogen too by renaming the plugin directories inside bundle, but I haven't tested it.
I'm still looking for a more general answer to this load-order issue
As far as I know, you can't really do it with Pathogen. It is really easy with NeoBundle. Pathogen is really minimal, it doesn't provide you with a lot of flexibility - it does only one thing and does it well. If you're looking for configurability, I think you're using the wrong tool.
EDIT: Not really sure about ftplugins, but bundles in general are loaded as you specify them (with Vundle/NeoBundle). So I realise that this maybe is not the most relevant of answers.

howto change location of .vimrc and .vim

How can I change the location of the .vim folder and the .vimrc file so that I can use two (or more) independent versions of vim? Is there a way to configure that while compiling vim from source? (maybe an entry in the feature.h?)
Why do I want to do such a thing?:
I have to work on project that use python2 as well as python3, therefore I want to have two independent vim setups with different plugins, configurations etc. Moreover, one version has to be compiled with +python, the other with +python3.
You can influence which ~/.vimrc is used via the -u vimrc-file command-line argument. Since this is the first initialization, you can then influence from where plugins are loaded (i.e. the .vim location) by modifying 'runtimepath' in there.
Note that for editing Python files of different versions, those settings (like indent, completion sources, etc.) are taken from filetype plugins which are sourced for every buffer separately, so it should be possible to even edit both Python 2 and 3 in the same Vim instance. (Unless you have some badly written plugins that define global stuff.) So for that, some sort of per-buffer configuration (some :autocmds on the project path, or some more elaborate solution (search for localrc plugins or questions about project vimrc here) might suffice already.
Also note that when the Python interpreter (which you'd only need for Python-based plugins and some interactive :py commands, not for editing Python) is compiled in with dynamic linking (which is the default at least on Windows), you can have both Python 2 and 3 support in the same Vim binary.
I think the easiest solution would be just to let pathogen handle your runtimepath for you.
pathogen#infect() can take paths that specify different directories that you can use for your bundle directory.
So if your .vim directory would look like this
.vim/
autoload/
pathogen.vim
bundle_python2/
<plugins>
bundle_python3/
<other plugins>
Then inside one of your vimrc for python 2 specific stuff you would have
call pathogen#infect('bundle_python2/{}')
and for python 3 specific stuff you would have
call pathogen#infect('bundle_python3/{}')
Since each plugin folder is really just a .vim folder you can place your python specific configuration stuff in a folder of the corresponding bundle and pretend its a .vim.
This structure also has the added benefit that you can change both configurations at the same time if you feel like it by putting common stuff in .vim normally.
You can also pass multiple bundle directories if you feel like to pathogen so you can have plugins that are shared without duplicating files. You just do this by passing multiple paths to pathogen#infect('bundle/{}', 'bundle_python3/{}')
After this is all done you can just create aliases for vim to call the correct vimrc file.
I found a way to do this!
You can just create a fake $HOME, whose contents are simply the .vim folder and .vimrc. Then, when running vim, set the HOME environment variable to that folder, and change it back on VimEnter.
Run vim with:
OLD_HOME="$HOME" HOME="$FAKE_HOME" vim
Add this to your .vimrc:
autocmd VimEnter * let $HOME = $OLD_HOME
On Windows you can use
let $HOME = $HOMEDRIVE.$HOMEPATH
insetead, no need to store the old home.
This works, but if you use $HOME inside your vimrc or any plugins will see the old value, it might affect them somehow. So far I haven't seen it.
Note: I don't really recommend doing this.
If you really really want to recompile vim so that it uses a different vimrc and different configuration directory take a look at src/feature.h
Search this file for USR_VIMRC_FILE. Uncomment it and place the name of your vimrc here. This will change the defualt vimrc file.
So it should look something like this
#define USR_VIMRC_FILE "~/path/to/vimrc"
Inside src/os_unix.h or src/os_mac.h and search for DFLT_RUNTIMEPATH. Change all instance of ~/.vim to whatever folder you want. This should set the default runtime path that vim searches for settings.

Vim In-File Commands

I'm after a means by which I can add additional commands to a text file via vim. For example, just as you can do something like this:
# vim:syntax=foo
I'd like to do something like:
# vim:option call matchadd('Special', '\(REQUIRED\|OPTIONAL\)')
Any ideas? I know I can write a syntax file, but this is not what I'm after for now.
Vim modeline syntax (see :help modeline) is not intended to specify commands
to execute during file opening. That is exactly what autocommands is for (see
:help autocommand). What you are trying to do should be an autocommand
similar the following.
autocmd FileType foo call matchadd('Special', '\(REQUIRED\|OPTIONAL\)')
or
autocmd BufReadPost *.foo call matchadd('Special', '\(REQUIRED\|OPTIONAL\)')
(Here instead of *.foo you can use any pattern that matches path or filename
(or both) of the target file.)
If the configuration you are setting up is local to some files or a project,
and you don't want to pollute your .vimrc with those autocmds, use
localvimrc plugin. It allows you to have a "local" .vimrc file next to
your target file or project folder. Script stored in that .lvimrc is
executed when you open files in the same directory where the "local" .vimrc
is, or in its subdirectories. Autocommands shown above (or any other
configurations) can be stored in a .lvimrc file local the project. For
details about localvimrc configuration see the homepage of the plugin.
This isn't an answer to your question, but I have also searched for Truth, and this question here is the closest one to it:
Vim: How to execute selected text as vim commands
It isn't automatic, but potentially only one keypress away it's close enough. :)
My ModelineCommands plugin extends Vim's built-in modelines to execute any Ex command(s) when a file is opened. A set of configurable validators examine the commands and can verify the correctness of an optional command digest, in order to prevent the execution of potentially malicious commands from unknown sources. (That's the main reason why Vim doesn't offer this feature!) This way, you could restrict the commands to only simple :let, or have the plugin query you to confirm execution of anything that isn't signed with your own secret key.

Resources