Running Command Asynchronously inside Neovim
When I am writing some prototyping code inside Neovim, I want to run the script
without going to the terminal and typing
python toy_script.py. Of course, we
:!python % in the command line to run the script (see
:h :!). The
problem is that running external command will block Nvim/Vim, and we can not
move the cursor until the script finishes running.
Of course, on Linux and Mac, you can use
!python % & to run the script in the
background, but you can not get the output of the script.
Asynchronous command in Nvim/Vim
Fortunately, both Neovim and Vim provides the job feature to run external command asynchronously. However, to use those features, you have to write non-trivial amount of code. Thanks to plugins like vim-dispatch and asyncrun.vim, we can use this feature easily.
In this post, I would like to share how to set up asyncrun.vim and use it. First, you can install it with vim-plug:
It provides the
AsyncRun command to run external shell commands asynchronously. For example, to run the current Python script, you can use the following command:
" use quote to avoid spaces in file names :AsyncRun python "%"
The above command will run current script in the background without blocking Neovim. You can still edit the source code as you will when the program is running..
Asyncrun.vim will put the output of the command in the quickfix list. To see the command output, use
:copen to open the quickfix window. You can also set up a config to open the quickfix window automatically when you use
AsyncRun. Just add the following setting to your
init.vim or vimrc:
let g:asyncrun_open = 6
Then a quickfix window of 6 line tall will be opened automatically after asyncrun starts.
Python related issues
Command output encoding
When you use asyncrun.vim on Windows, you may find that Chinese characters may not be displayed properly in the quickfix window. That is because the command output encoding on Windows may not be the same with the encoding you use (suppose you are using
utf-8 encoding). You can set up the variable
gbk encoding to solve this issue:
if has('win32') " Command output encoding for Windows let g:asyncrun_encs = 'gbk' endif
Then Chinese characters should display properly.
Display command output in real time
When python script is running in background, the output is buffered, i.e., you can not see the script output immediately after a
print() statement is executed. You will only see the output after cache buffer is full or when the script finishes execution. There are two easy ways to fix this issue.
The first is to add
PYTHONUNBUFFERED variable in your
init.vim or vimrc:
Or you need to run python command with
:AsyncRun python -u "%"
We can also create a shortcut to execute script quickly:
augroup python_file autocmd! autocmd FileType python nnoremap <F9> :AsyncRun python -u "%"<CR> augroup END
License CC BY-NC-ND 4.0