HOWTO: Use Vim as a manpager

Vim has a built-in manpage viewer plugin. So, the first thing to do is to make vim always load that plugin.

In my .vimrc add the following:
Code:
" Manpage plugin
runtime ftplugin/man.vim

The next thing we need to do is to tell our shell to use Vim as a manpager. In my .zshrc (you may use a different shell so make adjustments as necessary) I've added the following:
Code:
MANPAGER="vim -M +MANPAGER -"
export MANPAGER

But when viewing manpages I like using 'q' to quit (like when using more(1) or less(1)). To get that functionality, we change the above to add the mapping 'q' for quit.
Code:
MANPAGER="vim -M +MANPAGER -c 'map q :q<CR>' -"
export MANPAGER

Finally, you can use your own, or adjust a default, colorscheme to view man pages with more/different colors.

What we're going to do now is to set some tamer default colors to a built-in color scheme as a demonstration. In my .vimrc, I add the following (for example) to modify the 'desert' colorscheme:
Code:
augroup my_colorschemes
  au!
  au Colorscheme desert hi Normal ctermbg=NONE
              \ | highlight Special ctermfg=240 cterm=NONE
                \ | highlight Comment ctermfg=245
              \ | highlight Type cterm=NONE
                \ | highlight Normal ctermfg=249
augroup END

And, now in our .zshrc we add the colorscheme to the vim-manpager command.

Code:
MANPAGER="vim -M +MANPAGER -c 'map q :q<CR>' -c 'colorscheme desert' -"
export MANPAGER

Enjoy.
 
Does anyone know a workaround to make MANWIDTH (see man(1)) get along with line numbers in vim? I'd like to have MANWIDTH=tty (for the manpage to be displayed over the whole width of the screen), but I'd also like to have line numbers displayed when I use vim as a manpager. And because the manpage itself is formatted for my MANWIDTH before it piped into vim (which will add line numbers), the very first line can not fit the entire screen and wraps.

Not such a big deal really, but I wonder can this possibly be solved or not? This doesn't work with the sysutils/vimpager either.
 
I do NOT have the 'MANWIDTH' env var set and my manpages display full width.

To get the line numbers with my solution outlined above you would just add "-c 'set nu'" to the 'manpager' variable in the .zshrc. -e.g.,
Code:
MANPAGER="vim -M +MANPAGER -c 'map q :q<CR>' -c 'set nu' -c 'colorscheme desert' -"
 
I have this in my global 'common.tcshrc' sourced in all my $HOME/.cshrc for [man

Bash:
    #-----------------------------------------------------------------------------------------------
    # Manual page settings
    #-----------------------------------------------------------------------------------------------
    setenv MANPAGER        less
    setenv MANWIDTH        "`echotc co`"
    # Set the with of manpages before to execute commands in case the console window was resized
    alias precmd           'set i = "`echotc co`" ; @ i = $i - 4 ; setenv MANWIDTH "$i" ; unset i; echo -n "\033]0;tcsh - ${tty}\a"'
    # Help shell command for `run-help` (see key binding)
    alias helpcommand      man
    # Apropos alias
    alias ?                'man -k'

in precmd alias I recalculate the MANWIDTH (in vt when change font size or in tmux when resize panel and in GUI when resize xterm window) to the width of the screen minus 4, you can set the amount you want, but this is for tcsh shell.
 
Thank you all for your suggestions. The solution above is only for tcsh(1), but I use sh(1) as my shell.

I made a simple patch for man(1), where introduced an additional environment variable, that can decrease the resulting screen width, when MANWIDTH set to tty. Here's the patch:

Diff:
diff --git a/usr.bin/man/man.1 b/usr.bin/man/man.1
index 707677ccce0..62317d938d0 100644
--- a/usr.bin/man/man.1
+++ b/usr.bin/man/man.1
@@ -353,6 +353,18 @@ Otherwise, if set to a special value
 .Ql tty ,
 and output is to a terminal,
 the pages may be displayed over the whole width of the screen.
+See also
+.Ev MANWIDTH_TTY_OFFSET .
+.It Ev MANWIDTH_TTY_OFFSET
+If
+.Ev MANWIDTH
+set to a special value
+.Ql tty ,
+specifies number of columns, by which the resulting width should be decreased.
+It may be useful when
+.Ev MANPAGER
+adds decorations (e.g. line numbers), which occupy horizontal space on the
+screen.
 .It Ev MANCOLOR
 If set, enables color support.
 .It Ev MANPAGER
diff --git a/usr.bin/man/man.sh b/usr.bin/man/man.sh
index 920223ce3c2..ea4df6b3ae0 100755
--- a/usr.bin/man/man.sh
+++ b/usr.bin/man/man.sh
@@ -706,6 +706,11 @@ man_setup_width() {
             if [ $2 -gt 80 ]; then
                 use_width=$(($2-2))
             fi
+            case "${MANWIDTH_TTY_OFFSET}" in
+            [0-9]*)
+                use_width=$((${use_width} - ${MANWIDTH_TTY_OFFSET}))
+                ;;
+            esac
         fi
         ;;
     esac

You can apply it to your /usr/src and install it like this:
Code:
$ git apply <man.patch
$ cd usr.bin/man
# make
# make install

Now you can set MANWIDTH_TTY_OFFSET environment variable in your shell startup script:
sh:
export MANWIDTH_TTY_OFFSET=3
and now you can freely add line numbers into your MANPAGER (vim, in my case) and the lines will still fit the screen.
 
Back
Top