Pathogen and Neocomplete, Supertab, Youcompleteme; how to enable disable bundles? - vim

I use Pathogen to load my plugins at startup.
Sometimes I use Neocomplete plugin, sometimes YouCompleteMe plugin and sometimes Supertab to complete words and sometimes I use no completer at all.
These plugins do not work together if they are all loaded in Pathogen.
That's why I decided to create a little menu at then end of my vimrc where I can chose which completer to use (the one that I want to use is the one I disable in pathogen). I can launch it with a shortcut key.
The list g:PATHO contains the plugins to disable in pathogen:
If I chose to use Supertab --> remove Supertab from g:PATHO, save g:PATHO and reload vimrc.
If I chose to use Neocomplete --> remove Neocomplete from g:PATHO, save g:PATHO and reload vimrc.
If I chose to use Youcompleteme --> remove Youcompleteme from g:PATHO, save g:PATHO and reload vimrc.
This is what I have at the start of my _vimrc
if !exists("g:PATHO")
let g:PATHO = ['YouCompleteMe','neocomplete.vim','supertab']
endif
let g:pathogen_disabled = g:PATHO
below in my _vimrc I have this command to save global variables in my viminfo file:
set viminfo+=!
(thanks to Ingo Karkat)
g:PATHO is written in viminfo but when I reload vimrc, the variable g:PATHO is not found because viminfo is not yet read at the start of _vimrc.
When is viminfo read in _vimrc?
How can I let pathogen read g:PATHO at vimrc startup?
(hope I made myself clear)

Did you read :help startup?
Your viminfo file is read very late in the initialization process, after your vimrc and all your plugins are sourced, so pathogen won't be able to compare the default g:PATHO that you hardcoded in your vimrc with the one in your viminfo.
Your viminfo file is read only once, late in the initialization process, and will never be re-read again during the life span of your session. Reloading your vimrc will never trigger that re-read and neither pathogen nor any other plugin will notice the change you hoped to persist.
You can try :rviminfo to re-read that file manually and autocmds on VimEnter or some other event but…
…modifying the g:pathogen_disabled variable during a session won't have the effect you want: it doesn't remove a plugin from your runtimepath and it doesn't "unsource" it either. You can reload your vimrc all you want with different values for that option, the result will always be the same: nothing.
What you need — beyond coming up with a convincing justification for such a weird idea or even for the fact that you have three freaking completion plugins in your config — is to find a way to effectively make the functions and variables and whatever of a specific plugin completely disappear from Vim's memory. And I believe you won't find it here.
As a side note, only one of the three plugins provides built-in commands to enable/disable it. That is a sensible design choice that, if it was more universally available, would make the life of plugin hoarders a lot easier.

Related

In Vim, how to I set an autocommand to be run after a plugin has loaded?

One of the Vim Plugins I use has a bug, causing it to set :syntax spell notoplevel. The bug is easily mitigated if I run the command :syntax spell toplevel after opening a file. However, I'm lazy and I'd like to put the fix in my init.vim / .vimrc file, so that it's run automatically.
How can I ensure that my fix is executed after the buggy plugin code, so that my setting is not overridden by the plugin?
Create a file in ~/.vim/after/plugin/ such as ~/.vim/after/plugin/fix-spell.vim containing the command you'd run without the colon:
syntax spell toplevel
The files in ~/.vim/after/plugin are sourced after your plugins have loaded, thus providing a convenient hook to change settings that might have been set by a plugin.
Alternatively, you can set it as an autocommand. There are a whole slew of events you can tie autocommands to (:help events for all of them). VimEnter is an event that fires after plugins are loaded, so you could set your command to run then with a line like this right in your vimrc:
autocmd VimEnter * syntax spell toplevel
That's what I am using to apply a plugin theme that is not available until after plugins load.

Is that correct `vim -S session` will load `.vimrc` again?

I found out all the settings in .vimrc actually are stored in session file. If that is the case, why vim -S session load .vimrc again? Why does vim design like this?
I have some commands in .vimrc and when I use vim -S, it causes problems because those commands should only be run once, not twice.
Thanks a lot.
My problematic vimrc block in mksession:
let g:netrw_banner = 0
let g:netrw_liststyle = 3
let g:netrw_browse_split = 4
let g:netrw_altv = 1
let g:netrw_winsize = 25
augroup ProjectDrawer
autocmd!
autocmd VimEnter * :Vexplore
autocmd TabNew * call feedkeys(":Vexplore\<CR>", 'n')
augroup END
What a session stores
What gets stored in a saved session is controlled by the :help 'sessionoptions' option. It's defaults are very conservative, aimed at not losing any ad-hoc mappings or changed options.
However, most users place their settings in the ~/.vimrc, use plugins and filetype plugins, and generally do not make up mappings or change settings on the fly. If that kind of workflow also applies to you, I'd suggest to remove the following values:
:set sessionoptions-=globals
:set sessionoptions-=localoptions
:set sessionoptions-=options
You may also want to remove buffers and resize, too. That change not just reduces the size of the saved session, it also prevents that an old session overrides any configuration that you've changed in your ~/.vimrc in the meantime.
vimrc reload
So, your ~/.vimrc isn't directly reloaded, but (with default 'sessionoptions'), a lot of options and variables are restored.
By using :augroup followed by :autocmd!, you've also avoided a frequent beginner's mistake: Without that, the autocmds would be redefined on each reload of your ~/.vimrc. The :autocmd! prevents that, and the :augroup makes that apply just to your own group.
sessions and special (plugin) buffers
A session should store all currently open buffers. Regular buffers contain file contents, and these can easily be reloaded when a session is opened again. Unfortunately, plugins (mis-)use buffers for their user interfaces (e.g. a sidebar, as by the netrw plugin), and Vim's session handling is not clever enough to distinguish between the two. But those plugin buffers have no corresponding file; instead, the plugin used command to directly build and modify its contents, often with the help of plugin variables that - see above - either are or aren't saved and restored.
Plugins would have to explicitly handle session restoration; I don't remember any plugin that does this, though. So often, you'll see an "empty" window restored, and the plugin may or may not recognize or reuse that. (And I think that's the problem you're asking about.)
The general recommendation is to close any plugin buffers before saving a session, either manually, or by writing a custom :Mksession wrapper that automates this for you. On session reload, your configuration may then create a fresh, functional plugin window again. (Or you have to trigger that manually.)
Not all the settings from the vimrc are stored in the session file (see :h mksession). The settings you see are specified in the :h sessionoptions option.
You can load a session without loading the vimrc by using vim -u NORC -S; however, you'll quickly see you're missing your desired baseline settings.
Which commands should only be run once? There are specific ways to prevent commands from running twice unnecessarily when sourcing your vimrc.
For instance, if the command that should only be run once is an autocmd you should use an augroup like so:
augroup vimrc
autocmd! " Remove all vimrc autocommands
au BufNewFile,BufRead *.html so <sfile>:h/html.vim
augroup END

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

Vim - ftplugin settings changes not updating for existing file

It seems like there's some odd caching-like behavior going on for files that I have already opened once in Vim. I have a file foo.txt that I opened, and then I change some of the settings in ~/.vim/after/ftplugin/text.vim, but those new settings do not appear in foo.txt. I can quit vim and reopen foo.txt, or reload with :e, or even :so ~/.vim/after/ftplugin/text.vim, but none of these seem to have an effect on foo.txt's settings. If I mv foo.txt bar.txt, the settings show up for bar.txt with no issues.
EDIT
It seems I can force the settings to reload for foo.txt with the following sequence:
:so ~/.vimrc
:so ~/.vim/after/ftplugin/text.vim
Questions:
Why is this necessary / why were the other settings not picked up?
Why was sourcing ~/.vimrc not enough? It applied settings that were directly specified in ~/.vimrc, but shouldn't the ftplugins have been loaded at the line filetype plugin indent on? Why was sourcing text.vim afterwards necessary?
Vim runtime consists of a few hundred files, I'm not sure why you expect Vim to monitor them continuously. It doesn't. These files are loaded at some well-defined (and documented) points, that's all there is to it.
In particular there is no safe way to reload your configuration. You can do things like :so ~/.vimrc, but unless you specifically wrote your vimrc to take that into account, there will be drawbacks (such as autocmds piling up). If you want to be safe you have to quit Vim and start it again. That's how Vim works.
Now, for ftplugins you might get away with something like this:
:setf text
(use the actual filetype instead of text). This works for simple set fubar options. It works because under the hood setf is actually a carefully written autocmd. It still breaks for more complicated constructs (such as autocmds or file-scoped variables), for the same reasons :so ~/.vimrc has drawbacks.
A few more precisions:
.vimrc is loaded once -> for defining global stuff
same thing with .gvimrc, loaded only with gvim after the .vimrc
plugins are loaded once as well, after the vimrc files -> for global stuff as well
autoloaded plugins are loaded on demand, once, whenever a function they define is invoked
ftplugins are loaded once per buffer (and possibly multiple times! as there may be multiple buffers requiring them to be sourced) -> for definitions that shall apply only to the current buffer that triggered its loading
there are also langmap scripts, syntax scripts, indentation scripts, and even the old macros/ scripts (loaded explicitly/manually)
some plugins provides local vimrcs (basically identical to ftplugins, but loaded depending on the current directory of a buffer, instead of its filetype).
As you see, all things are loaded once, only. If you want to load them several times, you'll have to do it manually and explicitly. That's why a few of us have a :Reload command that simplifies reloading any kind of script - mine is hidden in my collection of scripts: lh-misc -> plugin/vim-maintain.vim

Unmapping Vim Plugin mappings

Is there a way to unmap mappings set by plugins? I'm currently calling exe ":mapclear" before my custom mappings in my .vimrc file, but the plugin files appear to be sourced after the vimrc file does. I have to resource my vimrc file again for it to work as expected.
I'm using Pathogen for sourcing plugins, which are all contained in my ~/.vim/bundle folder.
You could write the part with the mappings in your .vimrc in another file, say MyMaps.vim, and put this file in ~/.vim/after/plugin/.
This should make your maps the default ones
Look also at the documentation of the plugins setting the mappings, some of them
allow you redifine or deactivate the default mappings.
While snooping around my various plugins, I've found a kind of solution.
Unfortunately, a lot of the plugins (such as vim-surround, and vim-align, which in turn uses cecutil) add commands to my mapleader. Since I realised there actually are some key mappings from plugins I do use, I decided to set my mapleader back to its default (backslash) at the end of my vimrc file to prevent overlap.
The only problem I came across were mappings that were set in functions. When using au FileType html call ConfigHTML(), for example, the ConfigHTML() function would actually get called after the mapleader is set back to backslash.

Resources