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.
Related
How can I get vim to execute a command depending on the file type?
Recently I have been editing a lot of Python files and comments autoindent to the 0th column.
One way to fix this is to run the command inoremap # X#<left><backspace><right>
How can I get this command to run every time I open a python (*.py) file for editing?
TL;DR
Use vim's filetype plugin mechanism.
File-type specific code
There are (at least) two solutions to this, with one preferable to the other.
autocmd FileType
This has already been posted as an answer, but the general form is
augroup your_group
autocmd!
autocmd FileType python your good code
augroup END
This works, and has the advantage of grouping code in your vimrc.
But there is a second, more powerful, probably more performant alternative. It
is my preferred
solution.
after/ftplugin
I've written
extensively about using filetype
plugins in vim.
The gist of it is that you need filetype detection and plugins (filetype plugin
on at a minimum, though you may want filetype plugin indent on). Then you
drop filetype specific code in ~/.vim/after/ftplugin/<filetype>.vim (or a few
variants, see :h add-filetype-plugin, :h ftplugin-name, :h ftplugin).
So ultimately,
" ~/.vim/after/ftplugin/python.vim
inoremap # X#<left><backspace><right>
A few notes
It is a good practice to set b:undo_ftplugin properly: it helps (trust me).
You can borrow my undo script on
Github.
Consider using <buffer>, -buffer, setlocal, and <LocalLeader> where
possible. This is for local stuff, after all.
On power
A script gives you more flexibility than a single line of autocommands. You have
to jump through more hoops to do anything complex in autocommands, where in a
script they can just sit. Besides, you feel more like you're writing a program
(which you are) than a one off config.
The modularity is also perfect for organization: all your python customization
code is in one place.
And it's a lot less typing :)
On performance
I have not measured anything. Don't shoot me.
Having lots of autocommands can slow down vim, because they have to be checked
when their events fire. Rather than clog up the autocommands with filetype
stuff, use a file that is already going to be sourced for you (an ftplugin).
By piggybacking on an existing customization mechanic, you get all the benefit
and none of the risk. Again, it is almost certainly more efficient to let vim
source a file on demand for you then to try to reimplement it's ftplugin wheel.
Does this solve your issue?
au FileType python inoremap # X#<left><backspace><right>
This autocommand runs your mapping for filetype python
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.
For example https://www.ffmpeg.org/developer.html#Editor-configuration requires specific set of rules, but for my projects I usually prefer different one.
It would be great to have several named groups of formatting options for different projects and switching between them easily without modifying .vimrc
Vim does not have a concept of project so it has no native way to do such a thing. But don't let that get you down. We can still accomplish such a goal.
set exrc
set exrc
This enables the reading of .vimrc, .exrc and .gvimrc in the current directory. However this means you must open vim with the correct current working directory and opening another project in the same vim instance will not switch your settings. See :h 'exrc' for more information.
Roll your own autocommands
Vim's autocommands are basically event handlers. You can handle an event like opening a buffer from a specific directory and run a command, like sourcing some config settings.
augroup ProjectSettings
autocmd!
autocmd BufRead /project1/* source ~/.vim/project1_settings.vim
autocmd BufRead /project2/* source ~/.vim/project2_settings.vim
augroup END
As long as your settings files use buffer local setting commands like setlocal and mappings/abbreviations with the <buffer> option, your settings will be applied to just the buffers in your project.
I believe one (maybe?) of Derek Wyatt's vim videos show a similar method to this.
See the following for more information:
:h :au
:h BufRead
:h :so
:h :setl
:h <buffer>
Plugins
Sometimes it is just easier to use someone else solutions. There are a few local vimrc plugins out there that help give you local settings:
localvimrc
localrc.vim
vim-addon-local-vimrc
Another nice plugin option may be using Tim Pope's vim-sleuth which heuristically changes indent setting based on the file or in the case of blank/new files other files of the same type.
If project navigation is up your alley then I would suggest you look at Tim Pope's projectionist plugin or a nice fuzzy finder.
Conclusion
There are many options to explore here and no real right answer. I personally suggest using the plugin approach as it the easiest. However I feel obligated to tell you I use Projectionist and a custom project plugin for my projects at work so I am biased.
I understand that the recommended method for defining filetype-specific behavior in Vim is with .vim files and filetype plugin option. To add settings for .html files, for instance, I would add filetype plugin on in my .vimrc and add the settings to ~/.vim/ftplugin/html.vim.
All examples of this method that I can find, however, are about popular existing filetypes like .html or .sql. Would the same fix work for custom-defined file types? Let's say I want to use a new filetype with the extension .newft. If I create ~/.vim/ftplugin/newft.vim with the settings for this new type and load somefile.newft, would Vim automatically detect its type and load newft.vim?
I'm asking this because this is exactly what I'm doing and it's not working so far. I'd like to know whether this is an error or an expected behavior of Vim.
:h new-filetype outlines the different ways to add support for a new filetype.
I recommend method A which is as simple as writing the following in ~/.vim/ftdetect/newft.vim:
autocmd BufRead,BufNewFile *.newft set filetype=newft
and letting Vim deal with the rest.
Assuming you have filetype plugin on in your ~/.vimrc, the example above will make Vim try to source ~/.vim/ftplugin/newft.vim each time you read or create a buffer associated with a *.newft file or do :setfiletype newft/:set filetype=newft on an existing buffer.
The instructions on the Vim site says to just put the file in the /syntax folder. This works all right and well. But, for me to use the syntax I must set the following
:set syntax=go
Every single time. So, I know I am doing something wrong. I just don't know what.
Here are some things from looking around,
My HTML5 syntax set is from Rodrigo's HTML5 omnicomplete function and syntax vimball file. Though this uses some installation script to get it going.
As far as I can tell this would be my first manual adding of syntax file.
Also, my VIMRUNTIME is not set, well because there is no syntax.vim file, so from reading the documentation I see it checks for files via synload.vim
I even read the "Making Your Own Syntax Files" section, which says that same as above with the syntax=go option. Am I supposed to be detecting the .go filetype as described in new filetype section?
How can I enable syntax highlighting for GO by default?
This is for Mac Snow Leopard.
I don't think it is this complicated but I decided to leave all the different documentation I skimmed. GO and Vim say to just add the file. But it is definitely not detecting it automatically
If you are using filetype detection in your ~/.vimrc file with the following line:
filetype plugin indent on
then you can place the file in the following folder:
~/.vim/after/ftplugin/go.vim
or for windows
~/vimfiles/...
For the filetype detection to work, would would want the autocmd in a file in the ftdetect folder:
~/.vim/ftdetect/go.vim
and the contents would be:
autocmd BufNewFile,BufReadPost *.go set filetype=go
Use autocmd:
au BufRead,BufNewFile *.go setlocal filetype=go