Search code examples
vim

Function triggered only once by a FileType event for the current buffer?


So I can do this: Assign a keymap that is only active in the current buffer upon triggering the FileType event for that buffer. The actual assignment happens only once, the keymap stays active only in that specific buffer.

autocmd FileType javascript nmap <buffer> <leader>3 <Plug>BananaTest

But why I can't do this?

autocmd FileType javascript call s:ExecuteHook('ft==javascript triggered.')

Is there a way to call a function the first time a buffer gets assigned a FileType of javascript? So only once, exiting and entering that buffer will not trigger the call again.

I would like to add that I'm trying to make this work without implementing a /ftplugin/javascript/javascript.vim kind of a solution.


Solution

  • --- EDIT ---

    After you clarified your intent…

    autocmd FileType javascript call Foo()
    

    is the proper autocommand for calling Foo() when the filetype of a buffer is set to javascript.

    That said, the recommendation below to move your filetype-specific stuff to a proper filetype plugin still stands. In this case:

    " in after/ftplugin/javascript.vim
    function! Foo()
        echo 'Hello from a JS file!'
    endfunction
    call Foo()
    nmap <buffer> <leader>3 <Plug>BananaTest
    

    --- ENDEDIT ---

    The :help FileType event is only triggered once in the lifecycle of a buffer: during its creation, when its filetype has been set.

    If you want something to happen every time you enter a buffer with a given filetype, the proper event is, get ready, :help BufEnter:

    autocmd BufEnter * if &filetype =~ 'javascript' | do something | endif
    

    Where we have…

    • a BufEnter autocommand,
    • that is triggered for every buffer,
    • that does something only if that buffer has a filetype containing javascript.

    But littering your vimrc with filetype-specific stuff is messy. Instead, create after/ftplugin/javascript.vim if it doesn't already exist and define your filetype-specific functions, mappings, and commands there.

    It should look something like this:

    " in after/ftplugin/javascript.vim
    nmap <buffer> <key> ...
    augroup JavaScript
        autocmd!
        autocmd BufEnter <buffer> ...
    augroup END