Dave L
Dave L

Reputation: 77

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!

Upvotes: 2

Views: 345

Answers (1)

Ingo Karkat
Ingo Karkat

Reputation: 172590

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

Upvotes: 2

Related Questions