I’ve started using VIM a year or so ago and I’ve never looked back. It’s a very powerful and (in my opinion) efficient text editor, favoured by many programmers. And it’s rival is Emacs.

You can do some very fancy stuff with VIM, but it takes time to learn. You can watch some videos by Derek Wyatt, which showcase what can be done with VIM and are relatively easy to learn from (even though VIM has a steep learning curve).

Batch embedding images in Markdown

First of all, images can be embeded in such way:
![Alt text](URL)

If you need to refresh your Markdown syntax knowledge, here’s the documentation by Daring Fireball.

Ok, so the first thing is that we need to get a list of images into VIM. How do we do that? VIM has a :r command, which can read input from files or commands and pastes it into the buffer.

Combine with ls and it’s done: :r!ls *.png

The bang (!) symbol marks, that we’ll read from a command instead of a file. The result should look like this:


Now that we have our filenames in the buffer, we can start converting them. There are multiple ways to do it, but I’ll show you two of them.


With macros you can do lots of repetetive stuff that you may not be able to or don’t know how to do with substitutions or other means.

q followed by a register will start recording the macro. If you hit q again, it will stop the recording.

Here’s the complete macro I used: yt.i![ESCpla(ESClxA)ESCj0

Let’s take a look at what it is doing:

  • yt.i![ESCp - provided that the cursor is standing at the beginning of the line, it will yank all text until a dot (in this case filename1) into a unnamed register. Then it will go into insert mode and insert ![. I’m not sure if this is handled by some VIM plugin or it’s a standard behavior, but my VIM auto closes with the right square bracket. Then we paste the yanked text with p. Now we have ![filename1]filename1.png in our first line.
  • la(ESClxA)ESC - l (lowercase letter L) moves the cursor to the right, we append text after the cursor with a and type in the left parentheses. Hit the ESCAPE key to go back to command mode. l (lowercase L) to move right and x to delete the right paren (which was autoinserted by VIM). Use A to append the right paren at the end of the filename and hit ESCAPE to go back to the command mode. If you have VIM-surround plugin - you can add parens with it.
  • j0 - j will move down and 0 (zero) will move back to the beginning of the line.


This approach is sort of easier as it’s pretty much a single command:


  • %s/match/replace_with is the substitution command
  • \(.*\)\.png$ will greedy match lines, ending in .png and will forget about the extension. It’s just regular Regex: . (dot) will match any character and * will try to match 0 or more characters. $ marks, that the match should end in .png
  • ![\1](\1.png) is the format we want to use here. \1 is the match we told VIM to memorize

Last words

It may look confusing at first, but actually it’s quite easy once you have a grasp of VIM syntax (well, and regex for the substitutions). However, as with everything else, learning them by muscle memory takes time.

If you’ve never used VIM in your life you may think “It’s too much of a hassle to process those 7 images. I could’ve done that in 20 seconds with Notepad!”, and you would probably be right. But you couldn’t be that quick if the amount of stuff to do would grow ten or hundred times. Besides, those 2 commands come in just under 30 characters each.

VIM is documented very well and the documentation is built in, so if you have any trouble with any commands, just type in :h command in command mode.