2

When I pipe text to vim I discovered that by using:

cat somefile | vim -

it works properly, whereas:

cat somefile | vim

makes a mess of the code. For example, type:

cat test.pl | vim

where test.pl is:

#!/bin/bash
while true
do
    # i like comments
    say "This line, and the next one, should not be comments"
done

and you end up with:

le true
do
    # i like comments
    #     say "This line, and the next one, should not be comments"
    #     done
    #

It's as if without the hyphen the text appears as if it's being typed, switching modes and extending comments when you press enter etc, whereas with the hyphen it's treated as if a filename containing the piped text was passed to vim. I cannot locate the relevant help on this. I'm pretty sure it's not a shell feature (I'm using Bash on a Red Hat box).

2 Answers 2

1

It's not a shell feature, but a common convention for command-line tools to interpret - argument as an instruction to read data from standard input. Your understanding of how it works is correct.

For documentation see :help --:

-

This argument can mean two things, depending on whether Ex mode is to be used.

Starting in Normal mode:

vim -
ex -v -

Start editing a new buffer, which is filled with text that is read from stdin. The commands that would normally be read from stdin will now be read from stderr. Example:

find . -name "*.c" -print | vim -

The buffer will be marked modified, because it contains text that needs to be saved. Except when in readonly mode, then the buffer is not marked modified. Example:

ls | view -

Case with stderr being used as a source of commands is quite unusual, so here's an example that demonstrates how it works:

$ ls
commands  input
$ cat -A commands
wcwwas^[wgUE:w output$
$ cat input
This is input text.
$ cat input | vim - 2< commands
Vim: Reading from stdin...
Vim: Error reading input, exiting...
Vim: Finished.
$ ls
commands  input  output
$ cat output
This was INPUT text.

(Not sure why it says "error reading input".)

4
  • 1
    You beat me to the punch by about 15 seconds :(
    – Rich
    Commented Oct 4, 2017 at 11:36
  • I'm marking your answer correct, but I find that help very confusing. I have no idea what it's talking about with the "..read from stderr" thing. I just did a find within /tmp and got permission denied which i can redirect via 2>err.txt and confirm it's writing to stderr but I see no such text inside vim when using | vim -.
    – user859
    Commented Oct 5, 2017 at 8:32
  • @DrEval Try this: codingkilledthecat.wordpress.com/2012/12/24/… The way I read that, it's not reading output sent to stderr. It's reading input from it.
    – Rich
    Commented Oct 5, 2017 at 8:45
  • @DrEval, see my edit for an example with stderr.
    – xaizek
    Commented Oct 5, 2017 at 9:04
1

I think you've explained what's happening quite well yourself!

The documentation for this can be found at :help --.

In general, help for Vim's command line arguments is at :help vim-arguments, with help for e.g. the specific argument -X at :help -X. Because :help - is unfortunately already occupied, an extra hyphen is added in this instance.

1
  • 1
    Yeah, I did search for help but there was no way I'd have known to type hyphen twice! Thanks!
    – user859
    Commented Oct 4, 2017 at 12:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.