Vim plugins declared in ftplugin do not work - vim

Gvim is behaving weird and I can't find the reason. I use Vundle, and all the plugins declared in my .vimrc are working fine. I declared some additional settings and plugins in .vim/after/ftplugin/java.vim.
The mappings work fine, but the plugins do not work. If I choose a different file in my current gvim session, I get those error messages:
Error detected while processing function vundle#config#bundle[2]..<SNR>14_check_bundle_name:
line 2:
Vundle error: Name collision for Plugin Raimondi/delimitMate. Plugin Raimondi/delimitMate previously used the name "delimitMate". Skipping Plugin Raimondi/delimitMate.
Vundle error: Name collision for Plugin artur-shaik/vim-javacomplete2...
[comment: same error message for all plugins declared in the ftplugin]
I noticed, that if I run :VundleInstall the plugins are suddenly working (the error messages stay when I change the file, no plugins are installed when I use the command).
Here is the beginning of my .vimrc:
syntax on
set guifont=Inconsolata\ Medium\ 12
set nocompatible
set t_Co=256
filetype off
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
" let Vundle manage Vundle, required
Plugin 'VundleVim/Vundle.vim'
"[comment: all plugins I use for every filetype]
call vundle#end() " required
filetype plugin indent on
and this is my java.vim file:
filetype off
"to automatically close brackets
Plugin 'Raimondi/delimitMate'
"omni-complete for Java
Plugin 'artur-shaik/vim-javacomplete2'
"use tab to navigate through insert completion
Plugin 'ervandew/supertab'
filetype plugin indent on
"needed to make javacomplete2 working properly
autocmd FileType java setlocal omnifunc=javacomplete#Complete
My OS is Ubuntu 16.04.

You're mistaken regarding what ftplugins are doing and what they should contain.
Ftplugins are loaded once per buffer, every time a new buffer is created/opened.
They are meant to contain buffer local definitions:
:map <buffer> keybinding action
:iab <buffer> keybinding expanded sequence
:setlocal option[=value]
:command -b CommandName :Action
:let b:option = value
set the localleader (but be certain it's done before any other ftplugin for the same filetype) (EDIT: localleader is actually a global setting, my mistake)
They could then load other things that work the same way with :runtime or :so. They could contain functions, but it's best to define them into autoload plugins since Vim7. They may contain buffer local menu definitions, but this requires a plugin as this is not standard.
They are definitively not meant to contain global definition like the ones you have defined. It's not really the place to load global plugins that'll stay activated afterwards.
I know that some plugins manager load plugins on the fly depending on the type of the file we work on. I've never shared this need when we are using properly defined ftplugins, and lightweight plugins that only define a few mappings and keep their functions into autoload plugins.
Last thing, ftplugins are supposed to contain anti reinclusion guards. On a typical scenario this is not that useful. Many use b:did_ftplugin for that purpose, but I avoid this variable as I prefer to have as many ftplugins (for a same filetype) as themes (one that specializes the brackets pairs, one that defines the mapping to automatically expand a switch statement from the type of a variable, one that defines abbreviations for control statements, and so on). As a consequence I cannot use the same guard for all files.

All your :Plugin commands are supposed to be between these two lines:
call vundle#begin()
" :Plugin commands go here
call vundle#end()
Try another plugin manager if you absolutely need lazy loading.

Related

Installed vim colorscheme is not be found at startup, but it can be set once vim is loaded

I have installed with Vundle this github colours theme. I installed is with :VundleInstall and it seems to work just fine. The directory ~/.vim/bundle/vim-colors-github is there. Indeed, I can switch the color scheme with colorscheme github.
Next, I have added the following lines to ~/.vimrc to make this change permanent:
" github colors
let g:github_colors_soft = 1
Plugin 'cormacrelf/vim-colors-github'
colorscheme github
But this raises the error "E185: colorscheme «github» not found".
It just doesn't work during the loading of vim!? What's going on here? I guess there is something that hasn't been set yet at the time of calling the change in the colorscheme. How could I debug this?
You seem to be missing the call to vundle#end() at the end of your plug-in configuration. See the quick start guide which shows an example of defining plug-ins in your vimrc:
call vundle#begin()
Plugin ...
call vundle#end() " required
filetype plugin indent on " required
In your case, adding those lines around your Plugin definition will most likely fix the issue:
" load plugins
call vundle#begin()
Plugin 'cormacrelf/vim-colors-github'
call vundle#end() " required
filetype plugin indent on " required
" github colors
let g:github_colors_soft = 1
colorscheme github
Also note that Vundle hasn't really been very thoroughly maintained. While there's nothing wrong with it, vim-plug is a compatible alternative (works the same way, uses similar configuration and similar commands) which is well maintained and offers improvements in terms of performance and features. I'd definitely recommend switching to vim-plug, particularly if you're getting started with a Vim plug-in manager of this style.
Color schemes are searched along 'runtimepath' and 'packpath'. Therefore they will only be found on startup if you install plugins with respect to :h packages (i.e. under 'packpath'), not under arbitrary ~/.vim/bundle.
As for Vundle and such you are expected to manually set up 'runtimepath', so that it includes all plugins before executing :colorscheme. For Vundle it is done by calling vundle#end().

How filetype plugin on changes loading

What occurs when the filetype plugin option is changed? For example, from the docs it says:
When loading filetype plugins has been enabled :filetype-plugin-on, options
will be set and mappings defined.
Does this mean that if filetype plugin is off, then vim will not add certain directories to the vim runtime? Or what exactly does this parameter do, I'm a bit confused?
What this command does, it simply loads a relevant script from $VIMRUNTIME.
For filetype plugin on it's $VIMRUNTIME/ftplugin.vim; for filetype plugin off it's $VIMRUNTIME/ftplugof.vim; for filetype off it's $VIMRUNTIME/ftoff.vim, and so on.
Basically ftoff.vim clears filetypedetect auto-group (the one which traps BufRead); and ftplugof.vim clears filetypeplugin group (then one which traps FileType).
I suggest to everyone who is interested in internals to explore the code himself. The source worth a thousand words.

Different vim files for different languages and task

I want to create different vim files for different task in vim. I know you you can create different vim files, which can be loaded on the fly based on the extension of the file. My problem is I am using vundle to maintain plugins and I really don't know how to separate these plugins in different files.
I searched about separating vim and I found you can use ftplugin, something like ftplugin/python.vim or ftplugin/matlab.vim. But I don't know should I write vundle part in each .vim file or everything should be in one vim file.
Please let me know if you need more information. Below is my current .vimrc file.
" Configuration file for vim
set modelines=0 " CVE-2007-2438
" Normally we use vim-extensions. If you want true vi-compatibility
" remove change the following statements
set nocompatible " Use Vim defaults instead of 100% vi compatibility
filetype off " required
" set the runtime path to include Vundle and initialize
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
" alternatively, pass a path where Vundle should install plugins
"call vundle#begin('~/some/path/here')
"===================================================================
"Plugins
" let Vundle manage Vundle, required
Plugin 'gmarik/Vundle.vim'
" For autocomplete
Bundle 'Valloric/YouCompleteMe'
" For folding
Plugin 'tmhedberg/SimpylFold'
" For indent python
Plugin 'vim-scripts/indentpython.vim'
" For syntax
Plugin 'w0rp/ale'
" Check Python files with flake8 and pylint.
let b:ale_linters = ['flake8', 'pylint']
" Fix Python files with autopep8 and yapf.
let b:ale_fixers = ['autopep8', 'yapf']
" Disable warnings about trailing whitespace for Python files.
let b:ale_warn_about_trailing_whitespace = 0
syntax on
" For color Schemes
"Plugin 'jnurmine/Zenburn'
Plugin 'flazz/vim-colorschemes'
Plugin 'morhetz/gruvbox'
" For PowerLine
"Plugin 'powerline/powerline', {'rtp': 'powerline/bindings/vim/'}
Plugin 'vim-airline/vim-airline'
Plugin 'vim-airline/vim-airline-themes'
"For the nerd tree
Plugin 'scrooloose/nerdtree'
" add all your plugins here (note older versions of Vundle
" used Bundle instead of Plugin)
" ...
" All of your Plugins must be added before the following line
call vundle#end() " required
filetype plugin indent on " required
"===================================================================
" For UTF-8
set encoding=utf-8
"System Clipboard
if has('mac')
set clipboard=unnamed
elseif has('unix')
set clipboard=unnamedplus
endif
"set Line Numbering
set nu
"to handle the backspace problem
set bs=2
"Set up mouse
set mouse=a
"For Highlighting searched text
set hlsearch
"For confirming before exit (save)
set confirm
"Maping Ctrl+A for select all
map <C-a> <esc>ggVG<CR>
"===================================================================
" Mapping NERDtree toggling
nmap <F6> :NERDTreeToggle<CR>
"===================================================================
"Few settings for plugins
" colorscheme
colorscheme py-darcula
" to see the docstrings for folded code
let g:SimpylFold_docstring_preview=1
let mapleader=" "
"The first line ensures that the auto-complete window goes away when you’re
"done with it, and the second defines a shortcut for goto definition (second
"one I need to learn)
let g:ycm_autoclose_preview_window_after_completion=1
let g:ycm_min_num_of_chars_for_completion = 1
"map <leader>g :YcmCompleter GoToDefinition<CR>
"To handle vitural env for YCM
let g:ycm_python_binary_path = 'python3'
Using separate configuration files is possible (you can override the default .vimrc via the -u {vimrc} command-line argument; a shell alias can make this very easy). However, this complexity should not be necessary for most users.
In particular, Vim has built-in scoping of settings for different types of files in the form of buffer-local options and filetype plugins. So, if you want different indentation for Python vs. text files, that should work out of the box. Even though you're globally installing a plugin like vim-scripts/indentpython.vim (via Vundle in your case), it will only activate on files where :setlocal filetype? returns python. (By the way, that plugin was last updated 9 years ago, and Vim now ships with a $VIMRUNTIME/indent/python.vim that's actively maintained.)
For global plugins, it usually doesn't harm to have them installed all the time, even though you might only use them with certain projects. Vim's autoload mechanism dynamically includes the main plugin functionality on demand to keep Vim startup time short. Activating different plugin sets only makes sense for very few advanced users (and these would already have very deep knowledge of Vim's plugin mechanisms and not need to ask such questions).
You'll find more information about this at :help filetypes and :help local-options.
As I understand, the existed plugins work fine but you want to know the proper way to write your own ones. Am I right?
If so, then you don’t have to write your plugins (or other vim files) in any relation to Vundle or any other plugin manager. All you need is:
Read :help rtp.
Create a folder for your files wherever your want.
Set up the runtimepath option to the new folder. Typically, it’s just adding the new path with += operator.
Knowing about the list of directories which are searched for runtime files, create the functionality you want to get.
Yet another time: leave Vundle if you’re writing your own vim file. Vundle,
like any other plugin manager, is just a convenient tool to retrieve the code from a github repository and to set up the rtp option according to the new data.

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.

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