DEV Community

Serhat Teker
Serhat Teker

Posted on • Originally published at tech.serhatteker.com on

How to Run External Commands Within Vim

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
Enter fullscreen mode Exit fullscreen mode

Within Vim it will be:

:!chmod +x %
Enter fullscreen mode Exit fullscreen mode

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 .
Enter fullscreen mode Exit fullscreen mode

In vim it will be:

:read !tree -L 2 .
Enter fullscreen mode Exit fullscreen mode

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 .
Enter fullscreen mode Exit fullscreen mode

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(".")
Enter fullscreen mode Exit fullscreen mode

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

nnoremap <F10> :execute getline(".")<CR>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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

# file.sh
...

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

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

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

# 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

...
Enter fullscreen mode Exit fullscreen mode

All done!

Discussion (0)