-
Notifications
You must be signed in to change notification settings - Fork 111
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 -la
screenshot:
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 . ' &')
endfunction
Try it with:
:AsyncRun -mode=term -pos=gnome ls -la
Screenshot:
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.