The Unix way... or why you actually want to use Vim
Tags: vim, unix, productivity, bash
Published: 2018-11-09 10:49:30

---
title: The Unix way... or why you actually want to use Vim
published: true
description: Using Vim is not (just) about impressing your friends with your knowledge of exciting commands. It's more about Unix...
cover_image: https://thepracticaldev.s3.amazonaws.com/i/sbkkvwlgfct6yt5660zm.jpg
tags: 
    - vim
    - unix
    - productivity
    - bash
---

I like [all](https://dev.to/vintharas/exploring-vim-4k1i) [the](https://dev.to/allanmacgregor/vim-is-the-perfect-ide-e80) [Vim](https://dev.to/hamza/vim-for-starters---the-minimum-you-need-to-know-3ob) [tutorials](https://dev.to/webdevchallenges/summary-a-brief-introduction-to-vim-gcf) on [Dev.to](https://dev.to/t/vim/top/infinity). 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'](https://en.wikipedia.org/wiki/Unix_philosophy), which is pretty long so let's get to the point, eh?

In the words of the Ancient Grand Master [Douglas McIlroy](https://en.wikipedia.org/wiki/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]

```bash
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` 

```bash
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]

```bash
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`](https://en.wikipedia.org/wiki/Shuf) on my computer, which shuffles the lines you send in:

```bash
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`](https://en.wikipedia.org/wiki/Head_(Unix)) will do - it can give us just the first line from the input:

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

and behold

```bash
> 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`](https://www.gnu.org/software/parallel/):

```bash
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`](https://stedolan.github.io/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](http://pandoc.org/):

```
:%! 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 editor[^4].

So I wrote [a short(ish) NodeJS script](https://github.com/gypsydave5/bins/blob/master/js2json) 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](https://sanctum.geek.nz/arabesque/vim-koans/):

>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`](http://harmful.cat-v.org/cat-v/).
[^3]: The idea was McIlroy, but the `|` symbol was all [Ken Thompson](https://en.wikipedia.org/wiki/Pipeline_(Unix)#History). 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`.