3

Every time I switch back and forth between two buffers, vim tries to re-load some file specific commands. The error message is

E174: Command already exists: add ! to replace it`

I am using filetype plugins to handle different preferences and commands for every time of file that I work with. For example, I have the following code set up in my ~/.vim/ftplugin/c.vim file:

" Build Shortcut
command CompileC !gcc %:p -o %:r
noremap <Leader>cc <esc>:CompileC<CR>

command RunC !./%:r
noremap <Leader>rr <esc>:RunC<CR>

I have only a rough understanding that vim needs a autocmd! to clear the previous autocommand group, but I do not know where to put this. Can anyone help?

0

2 Answers 2

4

Every time a new or existing file, which is not already open in a loaded buffer, is :edited or otherwise opened, vim triggers the FileType autocommand and runs the scripts in /ftplugin/.

To fix your error merely replace command with command!. It is also a good idea to use the -buffer flag to make buffer local commands.

3
  • Great! It works. If I understand right, now vim will still load my filetype commands every time the buffer is opened, but it will clear the filetype commands from the previous time the file was opened, and redefine them to be the same thing as before. Is this correct? Oct 7, 2017 at 19:32
  • 1
    @Mass. :edit indeed triggers filetype autocommand when we execute :e foo.ft in foo.ft buffer, but not from other buffers which is a more typical scenario. Oct 8, 2017 at 2:02
  • 1
    @ichbinallen almost correct- vim does not actually clear any previous commands, command! just tells vim to ignore any possible previous definition and re-define it. Normally, vim will not allow you to define again a command which is already defined. Keep in mind the command in your example is in the global scope, not tied to any buffer, so it exists in any buffer within vim after editing a c file.
    – Mass
    Oct 8, 2017 at 2:39
1

Ftplugins aren't loaded when you switch between buffers. They are loaded only when you open a buffer for the first time, or if you change it's filetype. It's easy to check. Add some :echomsg in your ftplugins, and play with buffers. As a rule, by default ftplugins are loaded only once per buffer: when the buffer is opened/created -- or when we execute :e (foo.ft) from foo.ft buffer, otherwise :edit won't trigger filetype autocommands when editing a buffer already opened.

EDIT: I stand corrected, thanks @Mass. What I describe regarding the behaviour of :e is a consequence of set hidden in my .vimrc. Switching buffers by switching windows doesn't seems to be impacted by 'hidden', I observe it doesn't trigger any filetype autocommand.

As you define global stuff in your filetype plugin, well, it gets redefined every time the ftplugin gets loaded. If you open a java ftplugin where <Leader>cc is mapped to execute javac, you'd loose you mapping for compiling C.

The fix is easy: never define global things in ftplugins. Define only local things. The mappings shall be buffer local, as well as the commands.

Also, your mappings won't take advantage of one of the earlier feature of vim (compared to vi): the quickfix feature. Unless you make program is improperly configured (like the one shipped with mingw), you just need :make %< to compile mono-file projects. It'll works with C++, C, fortran...

4
  • I don't believe you that Ftplugins aren't loaded when switching between buffers. I added echomsg "Loading Ftplugin" to my c.vim file. Every time I switch to a filetype C buffer I get the message. Oct 7, 2017 at 22:20
  • You're not just switching to a buffer, you're switching to a new buffer. Just try to switch back to a buffer already opened (with :e after a :quit (not :bw/:bd), or by jumping between windows associated to different buffers) and you'll see no message. Ftplugins are triggered only once per buffer. If you observe something else, this means there is something out of place in your configuration. Oct 7, 2017 at 23:22
  • 1
    @LucHermitte do you maybe have set hidden? There is a huge difference in behavior when set versus not set. In particular, with nohidden, which is vim default, the FileType autocommand is executed at every :edit, :buffer, <C-^> , etc, even if you have opened the buffer previously.
    – Mass
    Oct 8, 2017 at 2:21
  • @Mass. Indeed. My mistake then. I've been using 'hidden' for so long I've forgotten its impact on this topic -- consequences which reinforce my choice. Oct 8, 2017 at 2:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.