-
Notifications
You must be signed in to change notification settings - Fork 116
Customize Runner
User-defined runners provide you the possibility to run commands in any way you want, which could be helpful when you want a command run in a tmux split, a new gnome-terminal window, or a floaterm window.
A runner is a function with one argument opts as a dictionary, from which stores the command string, working directory, and other parameters passed with :AsyncRun command. All the runners are required to register in g:asyncrun_runner so that AsyncRun can recognize them.
function! s:my_runner(opts)
echo "run: " . a:opts.cmd
endfunction
let g:asyncrun_runner = get(g:, 'asyncrun_runner', {})
let g:asyncrun_runner.test = function('s:my_runner')Than use:
:AsyncRun -mode=term -pos=test ls -la $(VIM_FILEDIR)When -mode=term and -pos=test are provided, runner test will be called. In this example, runner function s:my_runner does nothing but display the command in the bottom of your vim.
There is a opts argument in the runner function, which contains necessary information:
| Field | Need | Description | Example |
|---|---|---|---|
| cmd | (required) | Command string (macros have already been expanded here) | ls -la |
| cwd | (optional) | Working directory (will be an empty string if not provided) | /home/yourname/github |
| mode | (optional) | Running mode |
async, terminal/term, or vim
|
| pos | (optional) | Runner name or terminal position |
TAB, gnome, tmux, ... |
| option | (optional) | Runner option passed by :AsyncRun -option=xxx ...
|
... |
| close | (optional) | Close terminal after job finished | -close=1 |
| post | (optional) | A vim script needs to be executed after finished | -post=echo\ "done" ls -la |
| program | (optional) | Command modifier | -program=grep |
| focus | (optional) | if set to zero, the runner will not get focused | -focus=0 |
| encoding | (optional) | Command encoding | -encoding=gbk |
If -cwd=xxx is provided after :AsyncRun command, AsyncRun will temporarily change the
current working directory to the target position when calling runner function. So, you can
either pick the value in a:opts.cwd or use the return value from getcwd() .
When use the :AsyncRun command in the range mode, additional information can be use:
| Field | Description | Example |
|---|---|---|
| range | > 0 for range mode enabled | 0 |
| range_top | first line of the range, where range starts | 100 |
| range_bot | last line of the range, where range ends | 105 |
| range_buf | buffer id of the document | 1 |
Range support is not compulsory for runners, but it would be nice to provide this feature.
It is very easy to make the command run in a tmux pane with vimux:
function! s:run_tmux(opts)
" asyncrun has temporarily changed working directory for you
" getcwd() in the runner function is the target directory defined in `-cwd=xxx`
let cwd = getcwd()
call VimuxRunCommand('cd ' . shellescape(cwd) . '; ' . a:opts.cmd)
endfunction
let g:asyncrun_runner = get(g:, 'asyncrun_runner', {})
let g:asyncrun_runner.tmux = function('s:run_tmux')And you are able to use:
:AsyncRun -mode=term -pos=tmux ls -lascreenshot:

You can specify pane position (vertical or horizontal) and size, just check vimux's doc.
Another way to create a runner is to create a separated .vim file in the folder:
autoload/asyncrun/runner/
In one of your runtimepath, it will be automatically loaded in need. The script is required to provide a run function with the full name:
asyncrun#runner#{name}#run(opts)
For example, see gnome.vim in the autoload/asyncrun/runner folder:
function! asyncrun#runner#gnome#run(opts)
if !executable('gnome-terminal')
return asyncrun#utils#errmsg('gnome-terminal executable not find !')
endif
let cmds = []
let cmds += ['cd ' . shellescape(getcwd()) ]
let cmds += [a:opts.cmd]
let cmds += ['echo ""']
let cmds += ['read -n1 -rsp "press any key to continue ..."']
let text = shellescape(join(cmds, ";"))
let command = 'gnome-terminal -- bash -c ' . text
call system(command . ' &')
endfunctionTry it with:
:AsyncRun -mode=term -pos=gnome ls -laScreenshot:

In the runner folder, some pre-included runner script can be found:
| Runner | Description | Requirement | Link |
|---|---|---|---|
gnome |
run in a new gnome terminal | GNOME | gnome.vim |
gnome_tab |
run in a new gnome terminal tab | GNOME | gnome_tab.vim |
xterm |
run in a xterm window | xterm | xterm.vim |
tmux |
run in a separated tmux pane | Vimux | tmux.vim |
floaterm |
run in a new floaterm window | floaterm | floaterm.vim |
floaterm_reuse |
run in a reusable floaterm window | floaterm | floaterm_reuse.vim |
quickui |
run in a quickui window | vim-quickui | quickui.vim |
toggleterm |
run in a toggleterm window | toggleterm.nvim | toggleterm.vim |
xfce |
run in a new xfce terminal | xfce4-terminal | xfce.vim |
konsole |
run in a new konsole terminal | KDE | konsole.vim |
macos |
run in a macOS system terminal | macOS | macos.vim |
iterm |
run in a new iTerm2 tab | macOS + iTerm2 | iterm.vim |
They can be a good reference if you want to create a new runner.