Daily Archives: December 24, 2012

Piping Into Vim (and I/O Tidbits)

The Vim-related portion of this post is actually very small. In fact, it can be summed up in a single sentence: you can take the output of a pipe and place it into Vim for editing, without needing to use an intermediate file, by piping it to vim - (yes, the dash is significant). For example, grep foo bar.txt | vim - will grab all of the lines from bar.txt which contain “foo” and place them into a Vim buffer for editing.

If you look in the Vim manpage, you’ll see this functionality described as such:

The file to edit is read from stdin. Commands are read from stderr, which should be a tty.

At first glance, this might seem odd – the way many people think about the stdin, stdout, and stderr, it wouldn’t make much sense to “read” from something associated with “error output”.

The reality, however, is that all of these are merely pointers to devices. The devices themselves may support reading, writing, or both. In fact, for your normal interactive shell session, all 3 of the “standard” IO pointers all point to the same device. That device represents the terminal interface you’re using.

Note that this is a different concept of ‘device’ from that of hardware devices (e.g. keyboard, mouse, screen) – as far as command line I/O is concerned, “devices” are just things that can have data read from and/or written to them. For instance, an SSH session creates a virtual terminal device on the machine to which you connect, that proxies its input and output via your connection to the machine.

Once you understand this, the concept of “reading from stderr” makes a lot more sense – you’re not actually “reading from your output” but rather “reading from the same device that error output goes to by default”. Since stderr is typically output to your terminal, even if you redirect stdout (say, to a file), getting your input from stderr is a convenient way of accepting keyboard input from the terminal when stdin is being used by something else – in this case, from the pipe that’s filling the buffer with content for you to edit.