javavimneovimautocmd

Vim: BufNewFile autocmd does not work when inside filetype plugin


Background story: I want vim to generate a public class declaration when editing new java files, so I wrote the following augroup:

augroup generate_public_class_declaration_upon_creation
    au!
    autocmd BufNewFile *.java execute "normal! ipublic class " . expand('%:t:r') . "\<CR>{}\<Left>\<CR>\<CR>\<Up>\<Tab>" | startinsert
augroup END

Which works fine when put in .vimrc, but no longer functions after being transferred to ftplugin/java.vim. I tried some other events e.g. BufWritePre, BufWinEnter inside java.vim and nothing goes wrong. What's happening?


Solution

  • By the time that snippet is executed from your ftplugin it is already too late for catching the BufNewFile event.

    You can either leave it in your vimrc, where it is known to work, or modify it so that it can be executed from your ftplugin.

    Here is a quick and dirty solution:

    " in after/ftplugin/java.vim
    if !(bufname()->filereadable())
        execute "normal! ipublic class " . expand('%:t:r') . "\<CR>{}\<Left>\<CR>\<CR>\<Up>\<Tab>" | startinsert!
    endif
    

    where we check if there is a file for the current buffer before inserting our skeleton.

    Basically, when you do :e foo.java or $ vim foo.java, a buffer is created with the name foo.java, which is supposed to be the name of the associated file and can be retrieved with :help bufname(). If a file with that name doesn't exist, we check with :help filereadable(), we can insert the skeleton.

    Note the ! after startinsert: without it the insertion would happen before the <Tab>. See :help :startinsert.