9

I wrote a function in Bash to see man pages in Vim:

viman () { man "$@" | vim -R +":set ft=man" - ; }

This works fine, the only problem occurs if I pass a man page to it which doesn't exist. It prints that the man page doesn't exist but still opens vim with an empty buffer.
So, I changed the function to check the error code (which is 16 here) and exit if the page doesn't exist. The modified function looks somewhat like this:

viman () { man "$@" | [[ $? == 16 ]] && exit 1 | vim -R +":set ft=man" -  ; }

But, now it doesn't do anything.

I just want to quit the program if the man page doesn't exist, otherwise open the man page with vim.

5 Answers 5

8

Try this: capture the man output, and if successful launch vim

viman () { text=$(man "$@") && echo "$text" | vim -R +":set ft=man" - ; }
1
  • 1
    Capturing the output in a text is a simple and brilliant idea. Putting all things together the viman function is ready - viman () { text=$(man "$@") && echo "$text" | vim -R +":set ft=man nomod nonu noma nolist colorcolumn=" - ; }
    – Galilean
    Commented Dec 11, 2018 at 19:01
3

I like the idea of checking the man return code; you can't pipe to the test, though. You could just run man twice:

viman () { man "$@" >/dev/null 2>&1 && man "$@" | vim -R +":set ft=man" - ; }

This runs man ... | vim ... only if the first invocation of man was successful.

2

There's an environment variable called MANPAGER which can be used to make man call the command you want for displaying the manpage. The advantage of this is that you call man directly, and it won't run the pager at all if the manpage didn't exist.

So a wrapper script, say in ~/bin/vimman:

#! /bin/sh
vim -R +":set ft=man" -

With this in your shell initialisation files somewhere:

export MANPAGER="$HOME/bin/vimman"

And you can directly run man foo to manpages in Vim.

(Depending on the man command being used, you could also have:

export MANPAGER='vim -R +":set ft=man" -'

directly instead of a wrapper script.)


If you have a new enough Vim, you can use the --not-a-term option to stop Vim from complaining about stdin not being a TTY.


Shameless plug: I wrote a small plugin to facilitate using Vim as manpager.

2
  • This is also a nice solution, but let me ask you, I depend a lot on manpage than on google or at least try to, so I've written different wrappers to make manpager interesting , for there is a gui manpager that works with yelp, now I am wondering if the yelp will be able to work with this?
    – Galilean
    Commented Dec 12, 2018 at 3:12
  • @RitajitKundu if you're using yelp, you can directly open manpages in it: yelp man:foo (askubuntu.com/a/390095/158442)
    – muru
    Commented Dec 12, 2018 at 3:16
2
export MANPAGER='nvim +Man!'

Works for Bash and Zsh. Reports an error if the manual entry is not found, without opening Neovim.

See the documentation on how to use the Man plugin.

1

Based on this answer this starts vim and exits if there's nothing in the buffer. The disadvantage is that it starts vim so the screen "flashes". It also doesn't set an exit code when a man page isn't found.

viman () { vim -R +':set ft=man|exe !search(".")?"quit!":""' <(man "$@" 2>/dev/null); }

This is an improvement on Jeff Schaller's answer in that it doesn't load the the man page twice when it exists. It also doesn't load vim unnecessarily like my previous example. And it does set an exit code when there's no man page.

viman () { man -f "$@" >/dev/null 2>&1 && vim -R +":set ft=man" <(man "$@"); }

Both examples use Bash process substitution in order to avoid the "Vim: Reading from stdin..." message.

Neither loads the page into a variable.

1
  • An even more lightweight alternative to man -w may be man -w. Commented Dec 12, 2018 at 0:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .