and the rest
and the rest
I recently had a vim plugin prompt me for some text that would then be executed by the underlying shell. It didn't support autocompletion and it wasn't until then I realized my incessant mashing of tab when normally typing in the terminal. Life really shouldn't be this hard.
Autocompletion in vim is easy, you provide vim with a list of keywords to be searched through every time you hit tab. Let's build a small plugin that executes a python script with autocompletion for the python files in the current working directory. To execute a shell command from vim, type
:!shell-command from normal mode. So in our case, this would be something like
:!python example.py. Simple enough, let's translate this to a function and call it from a command!
function! s:RunPythonFile(filename) " Function arguments are accessed by a: and string concatenation is done by . " Weird, right? let command = '!python ' . a:filename execute(command) endfunction " -nargs=* Any number of arguments allowed, separated by whitespace (run python interpreter if no arguments) " <q-args> Quotes the input converting it into a string command! -nargs=* RunPython :call s:RunPythonFile(<q-args>)
After either painstakingly typing this into your command-line mode (accessed by
:) or pasting it into your .vimrc you can run a python script by typing
The easiest way to add autocompletion is to give the command the flag
completeOptions is whatever list you want to provide (
:help -complete and marvel). We want to provide our own so we need to add
-complete=custom,s:GetPythonFiles. Let's define the function
s:GetPythonFiles that will create our list.
function! s:GetPythonFiles(ArgLead, CmdLine, CursorPos) " A list of all python files in the current directory return system('ls *.py') endfunction
Simple as that! Now we have a working autocompletion!
There are many things to improve here that I leave as a challenge. For instance, can we pass more arguments to the
RunPython command (
:help join)? Can we extend the completion list to every python file on the filesystem (
:help globpath), or on a remote machine? And so on.
Hope you found this useful, and if you make a plugin, please save my fingers and add autocompletion.
Also, here is all the code for the lazy masses:
function! s:GetPythonFiles(ArgLead, CmdLine, CursorPos) return system("ls *.py") endfunction function! s:RunPythonFile(filename) let command = '!python ' . a:filename execute(command) endfunction " -nargs=* Any number of arguments allowed, separated by whitespace (python interpreter without arguments) " <q-args> Quotes the input converting it into a string command! -nargs=* -complete=custom,s:GetPythonFiles RunPython :call s:RunPythonFile(<q-args>)