Table of Contents
TL;DR
Today I learned about VIM's !! command, and it's amazing! It works by sending the selected range to an external program's stdin, and replaces those lines with its stdout.
Using an empty range
Sometimes you may want to put the contents of a file directly into you buffer, but you don't want to open up the file in a separate buffer, yank the contents, and put them in your desired buffer.
readme.txt
This is a readme file.
I need this file in a buffer!my_buffer
This is my buffer. I want the contents of the `readme.txt` file to go in this
file!
After switching to normal mode and navigating to the empty line (the last line in my_buffer), typing !!cat readme.txt will but the contents of readme.txt into my buffer, starting at my cursor!
my_buffer
This is my buffer. I want the contents of the `readme.txt` file to go in this
file!
This is a readme file.
I need this file in a buffer!Replacing a single line
Sometimes you want to view the content of a command's stdout in Vim. Usually what I do is run the command and pipe stdout into Vim's stdin (i.e. vim -).
Here's an example using the !! command. Say you have a JSON file that's been minified and you want to un-minify it. To accomplish this, we can use jq to read the file and put it's formatted JSON output into our buffer.
{"id":123,"name":"John Doe","age":34,"address":{"street":"123 Fake St","city":"Nowhere","zip":"98765"},"hobbies":["coding","gaming","nothing"],"active":true,"scores":{"math":95,"science":88},"lastLogin":"2023-10-05T14:30:00Z"}After switching to Vim's normal mode and putting my cursor over the line with the minified JSON, when I type !!jq<CR>, the single line of minified JSON is replaced with multiple lines of perfectly-formatted JSON -- magic!
{
"id": 123,
"name": "John Doe",
"age": 34,
"address": {
"street": "123 Fake St",
"city": "Nowhere",
"zip": "98765"
},
"hobbies": [
"coding",
"gaming",
"nothing"
],
"active": true,
"scores": {
"math": 95,
"science": 88
},
"lastLogin": "2023-10-05T14:30:00Z"
}Replacing a range
Here's another contrived example. You have a list of strings and you need to sort them and edit them in a buffer. Let's ignore that Vim has a built-in sort command (:h sort), so we need to use sort from GNU coreutils. One way you might accomplish this task is:
- save the list of strings to a file
- run GNU
sorton the file, saving the output to a separate file - open the sorted file in Vim
- yank the sorted lines
- put the sorted lines into the desired location in your destination buffer
This is a pretty lengthy task. Maybe we can shorten it. How about we:
- save the list of strings to a file
- run GNU
sorton the file, piping the output to Vim'sstdin(vim -) - yank the sorted lines
- put the sorted lines into the desired location in your destination buffer
That's better- we got rid of the intermediate file containing our sorted strings, but it's still a bit lengthy.
There's probably some other ways you can accomplish this process a bit quicker, but instead of going over every possible scenario, let's see how you'd do this with the !! command:
- using the range of strings, run
!!sort
Yep, that's it. One step. Let's have a closer look.
Here are some notes. I need these to keep organized!
TO-DO List:
- fix the leaky faucet
- walk the dog
- take out the trash
Grocery List:
- milk
- ground beef
- butter
- eggsLet's say I want to sort my grocery list- I think it'll be easier to take inventory of what I need if it's in alphabetical order. I'll position my cursor on the "butter" line in my grocery list and -- in normal mode -- type 4!!sort<CR>. Et voilĂ -- my grocery list is now sorted:
Here are some notes. I need these to keep organized!
TO-DO List:
- fix the leaky faucet
- walk the dog
- take out the trash
Grocery List:
- butter
- eggs
- ground beef
- milk