Can you have file type-specific key bindings in Vim?

Vim

Vim Problem Overview


In my .vimrc file, I have a key binding for commenting out that inserts double slashes (//) at the start of a line:

" the mappings below are for commenting blocks of text
:map <C-G> :s/^/\/\//<Esc><Esc>
:map <C-T> :s/\/\/// <Esc><Esc>

However, when I’m editing Python scripts, I want to change that to a # sign for comments

I have a Python.vim file in my .vim/ftdetect folder that also has settings for tab widths, etc. What is the code to override the keybindings if possible, so that I have Python use:

" the mappings below are for commenting blocks of text
:map <C-G> :s/^/#/<Esc><Esc>
:map <C-T> :s/#/ <Esc><Esc>

Vim Solutions


Solution 1 - Vim

You can use :map <buffer> ... to make a local mapping just for the active buffer. This requires that your Vim was compiled with +localmap.

So you can do something like

autocmd FileType python map <buffer> <C-G> ...

Solution 2 - Vim

The ftdetect folder is for scripts of filetype detection. Filetype plugins must be inside the ftplugin folder. The filetype must be included in the file name in one of the following three forms:

  • .../ftplugin/<filetype>.vim
  • .../ftplugin/<filetype>_foo.vim
  • .../ftplugin/<filetype>/foo.vim

For instance, you can map comments for the cpp filetype putting the following inside the .../ftplugin/cpp_mine.vim:

:map <buffer> <C-G> :s/^/\/\//<Esc><Esc>
:map <buffer> <C-T> :s/\/\/// <Esc><Esc>

Solution 3 - Vim

I prefer to have my configuration in a single file so I use the autocmd approach.

augroup pscbindings
  autocmd! pscbindings
  autocmd Filetype purescript nmap <buffer> <silent> K :Ptype<CR>
  autocmd Filetype purescript nmap <buffer> <silent> <leader>pr :Prebuild!<CR>
augroup end

Vim doesn't clear set autocmds when you source your vimrc, so starting vim, changing something in your vimrc and running :so ~/.vimrc would define autocmds twice. That's why the bindings are grouped and cleared with autocmd! group_name. You can read more here.

Since mappings are applied to every buffer by default, and you want to change them for buffers matching the filetype only, the <buffer> modifier is in there, limiting the mappings to the local buffer.

Solution 4 - Vim

Btw... if your primary problem is about commenting... you should check out 'nerdcommenter' plugin, its the fastest way to comment/uncomment your code in java/c/c++/python/dos_batch_file/etc etc.

Solution 5 - Vim

This is only a partial answer for people coming here having difficulties getting any ftplugin scripts working, but remember that your .vimrc (or a file that it sources) should contain

filetype plugin on

or

:filetype plugin on

for filetype-plugins to be executed when a file of a given type is loaded.

Solution 6 - Vim

I recommend the .../ftplugin/<filetype>.vim approach that freitass suggests, but in your specific case Vim Commentary will solve all of this for you.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJamesView Question on Stackoverflow
Solution 1 - VimhammarView Answer on Stackoverflow
Solution 2 - VimfreitassView Answer on Stackoverflow
Solution 3 - VimalextesView Answer on Stackoverflow
Solution 4 - VimticktockView Answer on Stackoverflow
Solution 5 - VimkoyaeView Answer on Stackoverflow
Solution 6 - VimFinlay McAfeeView Answer on Stackoverflow