Use Case I - Execute Mode

You create a script file then you want make it executable and you don’t want to leave your comfy editor to shell to execute that. How can we make it inside vim?

Typical shell command for that will be like:

$ chmod +x some_script_file.py

Within Vim it will be:

:!chmod +x %

When you want to execute external command, you add ! (bang) in the beginning of shell function/command following by filename. As you probably already know I used % for current file/buffer.

Use Case II - Write Output To File/Buffer

I have some command; I want to execute it and write the output to the current file.

Let’s assume my desired command is basic tree. In terminal it will be:

$ tree -L 2 .

In vim it will be:

:read !tree -L 2 .

The read command inserts the output of the external command on a new line below the current line in the file. If you want, you can also specify a particular line number - the output will be added after this particular line

:73read !tree -L 2 .

Use Case III - Running Directly From A Line

I have some command in my file and I want to execute a command directly from this line; I don’t want to copy+paste this long command to Vim’ command mode.

This is some kind of advanced method that we need to combine two things. First of all in order to execute a command from the buffer line you’re currently working on, run:

:execute getline(".")

However this violates our purpose: “running directly from line”. Therefore we need a mapping:

nnoremap <F10> :execute getline(".")<CR>

And if you want to visually select and execute add below mapping in your .vimrc|init.vim:

" Execute the line in VISUAL MODE
vnoremap <F10> :<c-u>exe join(getline("'<","'>"),'<bar>')<CR>

And the last thing you need to add :read ! to beginning of your command:

1
2
3
4
5
6
7
8
9
# file.sh
...

# the command you want to execute
tree -L 2 .

# add `:read !` before your command`
:read !tree -L 2 /tmp
...

After you press <F10> you will get the output under your command line:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# file.sh
...

# the command you want to execute
tree -L 2 .

# add `:read !` before your command`
:read !tree -L 2 /tmp
/tmp
├── Session.vim
├── com.apple.launchd.6UpVQs5arG
│   └── Listeners
├── com.google.Keystone
├── powerlog
└── tmux-501
    └── default

4 directories, 4 files

...

All done!