Search code examples
vimftplugin

Vim ftplugin executes c.vim instead of cpp.vim for C++ files


I am learing Vim and I want have set it up as IDE by mapping F5 key to compilation command which is decided by the filetype.

My ~/.vim/ftplugin/c.vim:

map <F5> :w<CR>:!clang % -o %:r.out && ./%:r.out<CR>

My ~/.vim/ftplugin/cpp.vim:

map <F5> :w<CR>:!clang++ -ggdb -pthread -std=c++11 % -o %:r.out && ./%:r.out<CR>

When I open a C++ file (with .cpp extension) and hit F5, the command from c.vim is executed. Why is this happening?

When I remove the file c.vim, then Vim loads cpp.vim and works as expected.


Solution

  • The cpp ftplugin that comes with vim has the following line:

    runtime! ftplugin/c.vim ftplugin/c_*.vim ftplugin/c/*.vim
    

    Which means it is going to source the ~/.vim/ftplugin/c.vim.

    A way to overcome this is to put your mappings in ~/.vim/after/ftplugin/cpp.vim and ~/.vim/after/ftplugin/c.vim files.

    But your problems don't stop there:

    • You are using :map where you probably want to at least supply a mode. nmap
    • You also should probably be using noremap so it would become nnoremap
    • Your mapping is global so it will stomp over your <f5> everytime you open a cpp and switch to a c file. You should make it local to the specific buffer. nnoremap <buffer>
    • You should probably also be setting makeprg accordingly so you can take advantage of :make and the quickfix list. e.g. setlocal makprg clang\ %\ -o\ %:r.out

    For more help see:

    :h :map
    :h :map-local
    :h 'makeprg'
    :h :make
    :h quickfix