pythonvimshebangautocmd

Autocomplete a python Shebang (in a non .py file) by mapping to an autocmd


I am learning Vim and I have successfully set up my .vimrc file such that whenever I make a new python .py file, the appropriate shebang and header are auto-generated. Yay me!

However, when building terminal pipelines I don't always like to include the .py extension for the programs I pipe to. Hence, the shebang won't auto-generate. Sad!

Without repeating what I wrote for the autocmd (which took much trial and error to write because that is how I learn), can I map a string like "pyhead" while in INSERT mode, or create a macro tied to the autocmd to easily implement my shebangbang when I choose not to use the .py extension? I feel as though a simple map to a command that already exists should prevent a cluttered .vimrc. I have placed my autocmd in an augroup as follows:

    augroup Shebang
        autocmd BufNewFile *.py 0put =\"#!/usr/bin/env python\<nl>...
                                     ...# -*-coding: utf-8 -*-\
                                     ...<nl>\<nl>\"
                                     ...|put ='#'.expand('%:t')
                                     ...|put =\"#<My_NAME>\"
                                     ...|put ='#LAST UPDATED: '.strftime('%m-%d-%Y')\|$ 
    augroup end

For clarity, the autocmd is all on one line, but I included three dots to indicate continuation (so that you wouldn't need to scroll). If this is a silly request, and there is an easy answer please reprimand. Thanks!


Solution

  • You can extract your long :put command into a function, and then :call that from within the :autocmd.

    function! InsertPythonShebang()
        0put =...
    endfunction
    
    autocmd BufNewFile *.py call InsertPythonShebang()
    

    You can then reuse the function in a mapping:

    nnoremap <Leader>py :call InsertPythonShebang()<CR>
    

    Or a custom command:

    command! -bar PyBang call InsertPythonShebang()
    

    Your suggestion of reacting on insertion of a special keyword would be possible, too, but I won't provide a solution because I think it's un-idiomatic, and the implementation would be more involved (especially if you want to reuse the :put, and not just the generated text). Also note that there are several snippets plugins that offer similar functionality (but again reusing the same string for your :autocmd would be a challenge).

    I would recommend a trigger on setting the python filetype on an empty buffer. In order to have syntax highlighting, you need to :setf python, anyway. (The built-in filetype detection would need the .py file extension, or an existing shebang line to work. Catch-22.)

    autocmd FileType python if line('$') == 1 && empty(getline(1)) | call InsertPythonShebang() | endif