Sunday, October 16, 2011

Browsing man pages in vim

So I've been playing around a lot with my .vimrc lately, and this is one of the more useful things I've added. I have forgotten where it came from exactly, but here it is:

let $GROFF_NO_SGR=1
source $VIMRUNTIME/ftplugin/man.vim
nmap K :Man <cword><CR>

What's it good for? The default key binding for K (that's "shift-k" I guess) in vim is to look up the word under the cursor using the man command. The sad thing about this process is that vim gets replaced by less (or whatever pager you happen to be using), and that once you're done reading the page, you have to press "Enter" one additional time to get back into vim and back to whatever you were doing. Kinda breaks your flow, you know?

Once you've added the three lines above to your .vimrc things are quite different. When you hit K, the man page opens as a new split window inside of vim so you're staying in the same environment. All the usual binds for switching between windows work, so you can keep the man page open while going back to your code. Better yet, the man page will be "syntax highlighted" using different colors for headings, text, and (you guessed it) references to other man pages. And the best thing? You can browse man pages the same way you browse tags: use "ctrl-]" to open another man page and use "ctrl-t" to "go back" to the previous one.

Now that's how man pages were supposed to be integrated with your editor. Very nice indeed... :-D

There's one small problem that I have not been able to work around yet: The original K could be preceded by the section number to look in, but this won't work in the replacement above. I am not enough of a vim hacker yet to add that capability. Shame on me?

Update: Actually, I forced myself to learn just enough of vimscript to cobble together something ugly for section numbers:

" experimental hack to get section numbers to work as well

function ManWrapper(n, w)
  if a:n > 0
    let cnt = a:n-line(".")+1
    execute "Man" cnt a:w
  else
    execute "Man" a:w 
  endif
endfunction 

com -count=0 -nargs=+ CMan :call ManWrapper(<count>, <f-args>)
nmap X :CMan <cword><cr>

Yes, I know, it's quite horrific! If you know this dreadful language better, please tell me how to rewrite this cleanly.

3 comments:

  1. Note you can use vim as your man pager at the standard shell too, with the highlighting and drill down benefits you mention.

    See the section towards the top of my:
    http://www.pixelbeat.org/settings/.bashrc

    ReplyDelete
  2. Thanks so much for this! I was inspired by your post, but agree that function is gross. So I played a little vim golf. Don't seem to need GROFF_NO_SGR on my newish Arch build, so just two lines sufficed.

    runtime ftplugin/man.vim
    nnoremap <silent>K :<C-U>exe "Man" v:count "<cword>"<CR>

    This also handles the numeric prefix for specifying a section.The Man command seems to happily eat whatever numbers you throw at it and will return a best guess if the section isn't found.

    ReplyDelete
    Replies
    1. Glad you found my hack useful as a starting point. And thank you in turn for finding a nicer version of doing things! :-)

      Delete