The Unix way... or why you actually want to use Vim

David Wickes - Nov 9 '18 - - Dev Community

I like all the Vim tutorials on Dev.to. They're great! They're good starting points. Please go and read them all!

But...

I'd like to tell you all the secret teaching of Vim. Bit of a sidetrack. You know, the stuff you get in the 36th chamber of Shaolin or whatever, because for some reason we love mixing up all our software development metaphors with martial arts and/or Zen Buddhism.1

Let me tell you about the Unix way...

Unix Philosophy

No, I'm not going to explain what Unix is. You have Google for that. Here's a link to the Wikipedia page on 'Unix philosophy', which is pretty long so let's get to the point, eh?

In the words of the Ancient Grand Master Douglas McIlroy:

Write programs that do one thing and do it well.

Which is easy to say but not easy to do. What if you want to do more than one thing?

Pipes

Pipes are the jewel of a Unix system. To me, its crowning glory. You send the output of one program as the input to another program - just like putting bits of hose pipe together and passing a stream of water through.

Say I wanted a random word with 'bob' in it somewhere. On a Unix like machine you will find a file with a lot of words in it - a dictionary. Mac and BSD systems have it at /usr/share/dict/words.

We can use the program cat to show it in a terminal:2

cat /usr/share/dict/words

But now we need to find all the words with 'bob' in ... well, we could open the file with grep

grep bob /usr/share/dict/words

but I find it more intuitive to pass the output of cat into grep using a pipe, which we write with the pipe symbol: |3

cat /usr/share/dict/words | grep bob

Well that gives me all the words with 'bob' in - how will I get a random one? There are a few ways of doing this, but here's one: I have the program shuf on my computer, which shuffles the lines you send in:

cat /usr/share/dict/words | grep bob | shuf

and now I just want one of the lines - it doesn't matter which one. Why not just the first one then? head will do - it can give us just the first line from the input:

cat /usr/share/dict/words | grep bob | shuf | head -1

and behold

> cat /usr/share/dict/words | grep bob | shuf | head -1
bobolink
> cat /usr/share/dict/words | grep bob | shuf | head -1
nabobish

What does that mean? I can use some other programs to help - I could open (at least on OSX) a URL with that word in it, using a handy program called parallel:

cat /usr/share/dict/words | grep bob | shuf | head -1 | parallel open https://en.wiktionary.org/w/index.php?title={}

and then... and then... and then...

The important lesson is this: we didn't write a new program. We didn't download a new random bob word generator. What we did was use a series of programs that do one thing (and one thing well) and glued them all together to get what we wanted.

But you promised us Vim!

Yes, yes. Vim. I've used Vim since I started developing - I used to write marketing emails using it to make writing marketing emails just a little bit more interesting (and therefore bearable). We always bang on about the keybindings in Vim - the magic of hjkl - but you can add those to almost any text editor these days.

So what do I think is great about Vim?

This:

:%!

For the Vim novitiates among us: : indicates we're entering a command. % is a reference to all the lines in the current buffer. And ! indicates we're going to run a command in the shell.

The above will pipe your current buffer through a shell command and replace the contents. Try it!

:%! shuf

Well that was fun, if highly destructive. But it can be a lot more useful. Want to reformat all the JSON in your buffer? jq is your friend:

:%! jq '.'

or maybe you'd like Python to do the same thing:

:%! python -m json.tool

view some Markdown as HTML? Try pandoc:

:%! pandoc 

You can do it with a range of lines, or a visual selection too - as always with Vim, help is available:

:h !

Now you can leverage other people's programs to extend your editor without installing extra modifications, or plugins, or using a new editor as you would with things like VSCode, Atom or Sublime. And if you find something useful, and use it over and over again, you can write a bit of VimL and to make the command easier to run.

Another advantage - by learning some of the simple, do-one-thing oriented programs that are available in a Unix environment, you'll be able to use them over and over again in more and more programs that you write.

Over to you

This becomes very real when you hit a problem that you've not got a tool for. For me, it was when I needed to translate some large JavaScript objects into JSON. A problem I couldn't see an easy way to complete in the editor4.

So I wrote a short(ish) NodeJS script that takes a stream of JavaScript and outputs a stream of JSON. Not beautiful, but effective.

Having written this once, with a pipe-friendly interface, I could now do this to a JavaScript object in a Vim buffer:

:%! js2json

or in the shell:

cat some.js | js2json | curl -X POST -d @- http://gimme-json.com

or maybe I'll never use it again.

But it's there. I've extended my editor by leveraging its ability to integrate with the programs I write. Thanks Vim! Thanks Unix!

Vi-Nature is Unix-Nature

Vim is not great because it impresses your friends with your knowledge of esoteric keystrokes,5 or because your elite touch typing skills allow you to churn out x-ity-x-billion characters per second by never taking your hands off the keyboard. These are fun things but they're shallow things. We should not obsess over them, and we should not be smug about knowing them.

Vim is great because it's everywhere - if you know Vim/vi then you've got an editor on most Unix systems you can use. It's great because you can integrate it into Unix tooling - and that's great because you can write those tools yourself because they're not that complicated and you're a programmer!

You'll see the same idea in other editors too. In the words of Master Wq:

Vim is not permanent. nvi is not permanent. vi itself is not permanent, only vi-nature. Emacs has vi-nature, nano has vi-nature, even Notepad has vi-nature. You narrow your sights, you grow attached [...]. You must leave. Come back when you have mastered Emacs.6

Where you can do the same with the simple Emacs command:

C-x h C-u M-| js2json

Happy hacking!


  1. It's all ninjas and koans, or its woodworking and 'craftmanship'. 

  2. Strictly speaking this is an abuse of cat

  3. The idea was McIlroy, but the | symbol was all Ken Thompson. Imagine that first day of using it - pipemania! 

  4. A hard way to solve it would have been to write a macro. That would have been throwaway and probably as time consuming.  

  5. You must all try ggg?G right now

  6. Only two editors missing, and you should try them both: ed and acme

. . . . . . . . . . . . . . . . . . .