asyncrun.vim: run commands in iterm2, tmux, or gnome/kde terminal
Tags: vim, linux, productivity, terminal
Published: 2022-01-04 19:08:56

---
title: asyncrun.vim: run commands in iterm2, tmux, or gnome/kde terminal
published: true
description: 
tags: #vim, #linux, #productivity, #terminal
//cover_image: https://direct_url_to_image.jpg
---

[asyncrun.vim](https://github.com/skywind3000/asyncrun.vim) was known as a shell command runner in the quickfix window. However, it first got released six years ago (2016), when the `+job` feature just became stable in vim `7.4.1829`. During these years, numerous issues have been addressed, and valuable feedbacks got collected.

At the beginning of 2022, I'd like to share some recent changes which may be helpful to improve your productivity.

## New runners

Both Vim and NeoVim got `+terminal` features for years, but some people still used to run new jobs in system terminals, like gnome-terminal, xfce-terminal, iterm2, or konsole. 

With the power of [user-defined runners](https://github.com/skywind3000/asyncrun.vim/wiki/Customize-Runner), you can run commands anywhere you want instead of in the quickfix window. Some pre-included runners can be used to interact with those external system terminals: 

| Runner | Description | Requirement |
|-|-|-|
| `gnome` | in a new gnome terminal | GNOME |
| `gnome_tab` | in a new gnome terminal tab | GNOME |
| `xterm` | in a xterm window | xterm |
| `tmux` | in another tmux split | [Vimux](https://github.com/preservim/vimux) |
| `xfce` | in a new xfce terminal | xfce4-terminal | 
| `konsole` | in a new konsole terminal | KDE | 
| `macos` | in a macOS system terminal | macOS | 
| `iterm` | in a new iterm2 tab | macOS + iTerm2 | 
| `external` | in a new cmd.exe window | Windows |

When using asyncrun with `-mode=term`, you can provide an option `-pos={runner}` to specify runner name:

```VimL
:AsyncRun -mode=term -pos=gnome      ls -la
:AsyncRun -mode=term -pos=floaterm   ls -la
:AsyncRun -mode=term -pos=tmux       ls -la 
```

When using `gnome`, `konsole`, `external`, or `xfce` runner in GVim, you can get exactly the same experience like starting a command-line program from IDEs:

![](https://raw.githubusercontent.com/skywind3000/images/master/p/asyncrun/runner-gnome2.png)

If you are using terminal vim, a new gnome-terminal tab, or iterm2 tab may be a good start:

![](https://github.com/skywind3000/images/raw/master/p/asyncrun_extra/p_gnome_tab.gif)

or perhaps in a tmux split:

![](https://github.com/skywind3000/images/raw/master/p/asyncrun_extra/p_tmux.gif)

Besides the system terminal, there are also runners for some most  famous internal terminal plugins:

| Runner | Description | Requirement |
|-|-|-|
| `floaterm` | in a new floaterm window | [floaterm](https://github.com/voldikss/vim-floaterm) | 
| `floaterm_reuse` | in a reusable floaterm window | [floaterm](https://github.com/voldikss/vim-floaterm)
| `quickui` | in a quickui window | [vim-quickui](https://github.com/skywind3000/vim-quickui) |
| `toggleterm` | in a toggleterm window | [toggleterm.nvim](https://github.com/akinsho/toggleterm.nvim) |
| `termhelp` | in terminal help | [vim-terminal-help](https://github.com/skywind3000/vim-terminal-help) |

Screenshot for the `floaterm` runner:

![](https://github.com/skywind3000/images/raw/master/p/asyncrun_extra/p_floaterm.gif)

Terminal-help:

![](https://github.com/skywind3000/images/raw/master/p/asyncrun_extra/p_help.gif) 

All runners are customizable, you can modify or define your own runners, see the [customize runner](https://github.com/skywind3000/asyncrun.vim/wiki/Customize-Runner) page.

## Internal terminal

Another exciting feature is interacting with (neo)vim's internal terminal:

```VimL
" run command in the internal-terminal in a new tab 
:AsyncRun -mode=term -pos=tab    ls -la
:AsyncRun -mode=term -pos=TAB    ls -la

" open on the left/right/top/bottom side
:AsyncRun -mode=term -pos=left   ls -la
:AsyncRun -mode=term -pos=right  ls -la
:AsyncRun -mode=term -pos=top    ls -la
:AsyncRun -mode=term -pos=bottom ls -la 
```

You may ask that you can directly use the builtin `:term xxx` command to start the internal terminal, what is the difference to use `:AsyncRun` for this ?

The main reasons are convenience and flexibility:

- Macros like `$(VIM_FILENAME)` or `$(VIM_ROOT)` can be expanded in the command:

    ```VimL
    :AsyncRun -mode=term -pos=TAB  ls -la $(VIM_FILEDIR)
    ```

- Working directory can be customized by `-cwd=` option:

    ```VimL
    :AsyncRun -mode=term -pos=TAB -cwd=~/github  ls -la
    ```

- Easier to specify the opening position and size:
   
    ```VimL  
    :AsyncRun -mode=term -pos=bottom -rows=8  ls -la
    :AsyncRun -mode=term -pos=right -cols=40  ls -la
    ```

- No distraction and prevent focus changing by providing `-focus=0` option:

    ```VimL 
    :AsyncRun -mode=term -pos=tab -focus=0  ls -la
    ```

- Can close the terminal window automatically when job is finished if `-close` option presents.

    ```VimL 
    :AsyncRun -mode=term -pos=tab -focus=0 -close ls -la
    ```

- Run a vim command when job finished by `-post=xxx`

    ```VimL
    :AsyncRun -mode=term -post=echo\ 'notify'   ls -la
    ```

And there are some more benefits:

- Environment variables like `$VIM_FILENAME` can be initialized correctly.
- Prevent listing terminal buffer in the buffer-list by `-listed=0`.
- Set `bufhidden` to `hide` for terminal buffer by `-hidden=1`.
- Reuse the previous terminal window by `-reuse`.
- Notify can be setup by `-post=xxx` option.
- Corresponding experience in both vim and neovim.

The most important thing is that vim/neovim's `:term` command can't escape complex strings correctly in Windows or some rare shells when arguments contain white spaces or quotes and bars. AsyncRun can pass arguments precisely as what they are.

My favorite terminal position is `-pos=TAB`, different with lower case `-pos=tab`, it will open a new terminal tab on the left side of my current tabpage:

![](https://raw.githubusercontent.com/skywind3000/images/master/p/asyncrun/mode_term_3.png) 

I use it a lot to execute the current file because when it is finished, the tab will close, and it will return to the previous tabpage where I was working.

Excluding macro variables substitution, some of the actions above can be achieved by original `:term` with one or more other commands. Still, asyncrun provides a unified interface for these trivial things in one command and eliminates the difference between vim and neovim.

## Summary

asyncrun.vim provides you with all the possible ways to run commands in vim with no compromise. Feel free to choose the one you like, and don't forget to check the [command specification](https://github.com/skywind3000/asyncrun.vim/wiki/Command-Specification) for more.

**Bonus**: If you find mapping asyncrun commands for different projects or file-types challenging, you may be benefit from a sibling plugin [asynctasks.vim](https://github.com/skywind3000/asynctasks.vim), it uses asyncrun as the backend and introduces vscode like task system in vim.


.