20

When using Vim to read from stdin, it prints a informative message:

$ echo foo | vim -
Vim: Reading from stdin...

$

This is just an example. The actual use doesn't allow shell constructs. vim <(echo foo) is not an option.

Can I suppress that using only Vim options and/or vimrc settings?


In case you do need to know what this is for, I'm trying to use Vim for reading manpages (shameless plug). GNU man doesn't allow shell constructs in MANPAGER, and by using ftplugin/man.vim and other things, I have successfully managed to have a comfortable experience using just MANPAGER="vim -". The last remaining annoyance is the unsightly message printed after every manpage that I viewed.

8
  • Using export MANPAGER='vim -c "%! col -b" -c "set ft=man nomod nolist ignorecase" -' or export MANPAGER="vim -" I see no problem? man ls opens the manpage as-expected. Commented Sep 8, 2015 at 19:29
  • @Carpetsmoker and after you close it?
    – muru
    Commented Sep 8, 2015 at 19:30
  • Nope, don't see anything... Commented Sep 8, 2015 at 19:32
  • @Carpetsmoker which version of Vim are you using? What about echo foo | vim -Nu NONE -
    – muru
    Commented Sep 8, 2015 at 19:33
  • In vim, : help less gives some info for using it as a pager.
    – mtklr
    Commented Sep 9, 2015 at 13:24

4 Answers 4

11

Starting with Vim 8.0.1308 (Nov 2017), you can use the "--not-a-term" option with "quit":

$ echo hello | vi - --not-a-term -esc '%p|q!'
hello

Or with "exit":

$ echo hello | vi - --not-a-term -esc 'x!/dev/stdout'
hello

http://github.com/vim/vim/issues/1552

4
  • As is, this is equivalent to cat, but it can still be useful for applying Vimscript to the input, e.g. +'runtime! syntax/2html.vim' to export highlighted text as styled HTML (assuming deduced or specified filetype). There are a few options other than the ones mentioned so far; the first that comes to mind is using mktemp to store the command's output and using this as Vim's input. You could add Vim's redirection and shell commands to 'paste' the command result into the buffer, but this takes some more work. (Vim script files can automate lengthy invocations instead of using aliases.)
    – John P
    Commented Oct 30, 2017 at 10:57
  • It might be possible to edit/paste output from a socket, which could be really useful if it were true. I still say the best option is a temp file, unless there are caveats worse than those for the accepted answer. For a given shell though, there may be an existing alias/builtin/syntax that simplifies some part of this process, like those listed in the manpage for zshmisc (redirections, etc.) One more - maybe you can escape the input and supply it as an argument after an argument entering insert mode, so it parses as though typed?
    – John P
    Commented Oct 30, 2017 at 11:17
  • I see --not-a-term in Vim 7.4.1689 in Ubuntu 16.04 (but not 7.4.8056 on a Mac), but it doesn't suppress the message. Commented Dec 11, 2018 at 23:48
  • @DennisWilliamson See the changelog by :help version8.txt. --not-a-term option itself was added in 7.4.1419 and its behavior was changed to also suppress the Reading from stdin... message in 8.0.1308. (By the way, the N files to edit message is also be suppressed from 8.1.1258)
    – ynn
    Commented Oct 20, 2019 at 15:13
12

The answer to your exact question:

Can I suppress that using only Vim options and/or vimrc settings?

is: no, it's not possible because of the following part of the code

    if (read_stdin)
    {
#ifndef ALWAYS_USE_GUI
        mch_msg(_("Vim: Reading from stdin...\n"));
#endif

which means that if you give - as argument to vim, then it'll mechanically show that message.

though, as a work around, if you use a file redirection instead of the - argument you'll get rid of the message:

echo "foo" | vim < /dev/tty

and here's an example of MANPAGE setting that just works™ (taken from the intertubes):

export MANPAGER='bash -c "vim -MRn -c \"set ft=man nomod nolist nospell nonu\" -c \"nm q :qa!<CR>\" -c \"nm <end> G\" -c \"nm <home> gg\"</dev/tty <(col -b)"'
8
  • 2
    When is ALWAYS_USE_GUI defined, do you know?
    – muru
    Commented Sep 9, 2015 at 8:46
  • 2
    see feature.h (it's done when ALWAYS_USE_GUI is not defined, so basically for all unix versions). Commented Sep 9, 2015 at 8:54
  • 2
    I cannot get the workaround echo "foo" | vim < /dev/tty work. Doing it gives [2]+ Stopped echo "foo" | vim < /dev/tty. Commented Jul 1, 2016 at 5:51
  • 2
    Like @LéoLéopoldHertz준영, the tty trick didn't work for me (gvim gives an empty document, vim gets real confused with the keyboard inputs, but at least it doesn't receive a SIGSTOP). I've had more luck with echo "foo" | gvim /dev/stdin (although the non-GUI vim will still issue a complaint about that: Vim: Warning: Input is not from a terminal).
    – Adam Katz
    Commented Jan 14, 2017 at 1:38
  • 2
    Well, forget my previous message. The trick in the answer is in <(col -b) part. That's essentially some sophisticated version of cat for printing man pages, and you can finally get rid of the vim's message with echo test | vim < /dev/tty <(cat> Commented Oct 25, 2018 at 8:37
2

In Vim, this issue has been addressed in 234d162 commit (>=v8.0.1387).

Solution: Don't show the message with --not-a-term was used.

So the message is only displayed when user hasn't redirected the stdin.


Similar issue has been addressed in the recent version of Neovim (>=v0.2.2-dev) which you could use instead of Vim.

Once NVim v0.2.2 is released, you should be able to run:

$ echo foo | nvim -

without having the message.

0
1
  1. With vim of version 8.0.1387 and newer you can use --not-a-term option.

  2. For older version use the following trick: $ echo foo | bash -c 'vim < /dev/tty <(cat)'

The first argument /dev/tty somehow tricks Vim to think the input comes from the keyboard. I guess, that's because isatty(3) returns True for that file. And the second argument simply passes-through everything from its standard input to Vim's standard input. Finally, bash -c prefix is required for the special construct <(...) to work if the shell doesn't support it. In bash the original solution can be simplified to $ echo foo | vim < /dev/tty <(cat)

2
  • Both of these are covered in existing answers or the question itself. What's new here?
    – muru
    Commented Oct 25, 2018 at 8:58
  • @muru It wasn't explained how the second case works, and people was wondering why it only worked in MANPAGE. Commented Oct 25, 2018 at 9:36

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.