Hello,
I've also experienced man.vim crashing when $MANPAGER had been already
defined to `col -b | vim -R -' in .bashrc. I took a look at the man.vim
file and came up with the following idea.
Instead of asking if $MANPAGER was defined, why not define it
temporarily for the call. It's possible to do this via
let tmp = tempname()
let $MANWIDTH = &tw ? &tw : 80
let manpager = shellescape('less -s') " Fixes problems when user has
defined $MANPAGER
silent execute "!MANPAGER=".manpager." /usr/bin/man ".args."| col -b >
".tmp
silent execute "pedit ".tmp
See the attachment for the complete reimplementation of GetPage(). I
also wanted to fix a couple of subtle shortcomings of the original script.
In my opinion, viewing man pages should mimic reading help pages which
is already reflected nicely in the mappings <C-]> and <C-t>. However, it
would also be nice to be able to double click the topics as one can do
in help files.
Man pages should also be closed when the last writable buffer is closed
in the current tab page, as is the case with help files. Now the user is
potentially left with two windows to the same shell script. The first
was used to spawn a man page via <Leader>K for example and the second
appeared unintentionally when the user rewinded man pages one time too
many.
Finally, all man pages shouldn't be only 'readonly' but also
'nomodifiable'.
All of these aspects are taken care of in the script you'll find in the
attachment. I post it to your consideration.
On Mon, 25 Jul 2011, Bram Moolenaar wrote:
Mike Mcewan wrote:
It's been a while since I reported a problem with the patch here and no
further comment has been made. I guess the majority of users out there are
probably using one of the pre-packaged versions of vim 7.3 and so this
problem hasn't come down the pipeline to hit them yet. I have seen one other
reference to the problem whilst browsing the web:
http://crumbtrail.chesmart.in/
I still don't think the original patch was the right solution here, but
until someone comes up with a better solution, I wonder if the the following
patch could be applied?
--- a/ftplugin/man.vim 2011-07-22 19:55:14.000000000 +0100
+++ b/ftplugin/man.vim 2011-07-24 17:55:49.000000000 +0100
@@ -17,7 +17,9 @@
" Ensure Vim is not recursively invoked (man-db does this)
" when doing ctrl-[ on a man page reference.
- let $MANPAGER = ""
+ if exists("$MANPAGER")
+ let $MANPAGER = ""
+ endif
" allow dot and dash in manual page name.
setlocal iskeyword+=\.,-
--
Elias Toivanen <[email protected]>
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
" Vim filetype plugin file
" Language: man
" Maintainer: SungHyun Nam <[email protected]>
" Last Change: Sun 24 Jul 2011 01:13:42 AM EEST
" Contributors: Elias Toivanen
" --------------------------------------------------------------------------"
" NOTES "
" "
" * Prevents all modifications of man pages and represents them "
" as `preview windows'. Man pages are not listed in the buffer "
" list and become hidden when closed. "
" "
" * Filetype specific mappings mimic those in Vim's help files. "
" <c-]> jumps to the topic under under cursor, whereas <c-t> "
" takes you back. You can also double click topics and "
" press <C-RigthMouse> to achieve the same results. "
" "
" * Provides two commands :Man and :Whatis and two corresponding "
" global mappings <Leader>K and <Leader>W that are enabled "
" by appending "
" "
" ru ftplugin/man.vim "
" "
" to .vimrc. The variable `mapleader' has to be defined to "
" make the mappings effective. The first command takes two "
" arguments `section' and `page', first of which is optional. "
" A preview window with the man page of `page' is opened if found. "
" The second command accepts one argument `page' and displays "
" a short description of the command in the commandline. Mappings "
" achieve the same results except the `section' and `page' arguments "
" are found by inspecting the word under the cursor. "
" "
" * Use Vim as your $MANPAGER in bash by appending "
" "
" MANPAGER='sh -ec "col -bx | vim -R -c \"set ft=man\" -"' "
" export MANPAGER "
" "
" to your .bashrc. "
" "
" --------------------------------------------------------------------------"
" --------------------------------------------- "
" Filetype specific settings "
" --------------------------------------------- "
if &ft == "man"
" Only do this when not done yet for this buffer
if exists("b:did_ftplugin")
finish
endif
let b:did_ftplugin = 1
setlocal ro nomod nomodifiable
setlocal bufhidden=hide
setlocal nobuflisted
setlocal nonu fdc=0
setlocal buftype=nofile
setlocal pvw mouse=a " Need mouse support for mappings
" Allow dot and dash in manual page name.
setlocal iskeyword+=\.,-
" Add mappings, unless the user didn't want this.
if !exists("no_plugin_maps") && !exists("no_man_maps")
nnoremap <buffer> <c-]> :call <SID>PreviewPageUnderCursor()<CR>
nnoremap <buffer> <2-LeftMouse> :call <SID>PreviewPageUnderCursor()<CR>
nnoremap <buffer> <c-t> :call <SID>ManPop()<CR>
nnoremap <buffer> <C-RightMouse> :call <SID>ManPop()<CR>
endif
endif
" --------------------------------------------- "
" Command to view man pages from any Vim buffer "
" --------------------------------------------- "
if !exists(":Man")
com -complete=shellcmd -nargs=+ Man try | call <SID>PreviewPage(<f-args>) |
catch /IOError/ | endtry
nmap <Leader>K :call <SID>PreviewPageUnderCursor()<CR>
com -complete=shellcmd -nargs=1 Whatis call <SID>Whatis(<f-args>)
nmap <Leader>W :call <SID>WhatisUnderCursor()<CR>
endif
" Define functions only once.
if !exists("*s:PreviewPage")
let s:man_sect_arg = ""
let s:man_find_arg = "-w"
let s:view_stack = []
try
" Override flags for UNIX System V
if !has("win32") && $OSTYPE !~ 'cygwin\|linux'
\&& system('uname -s') =~ "SunOS" && system('uname -r') =~ "^5"
let s:man_sect_arg = "-s"
let s:man_find_arg = "-l"
endif
catch /E145:/
" Ignore the error in restricted mode
endtry
function s:GetCmdArg(sect, page)
if a:sect == ''
return a:page
endif
return s:man_sect_arg.' '.a:sect.' '.a:page
endfunction
function s:IsValidPage(args)
let path = system('/usr/bin/man '.s:man_find_arg.' '.a:args)
let path = substitute(path, "\n", "", "g")
return filereadable(path) ? 1 : 0
endfunction
function s:PreviewPage(...)
" Examples
" :call <SID>PreviewPage(7, regex)
" :call <SID>PreviewPage(bash)
if a:0 >= 2
let sect = a:1
let page = a:2
elseif a:0 >= 1
let sect = ""
let page = a:1
else
return
endif
" To support: nmap K :Man <cword>
if page == '<cword>'
let page = expand('<cword>')
endif
let args = <SID>GetCmdArg(sect, page)
if !<SID>IsValidPage(args)
let trail = sect ? "in section ".sect : ""
echo "No manual entry for `".page."' ".trail
throw 'IOError'
endif
let tmp = tempname()
let $MANWIDTH = &tw ? &tw : 80
let manpager = shellescape('less -s') " Fixes problems when user has
defined $MANPAGER
silent execute "!MANPAGER=".manpager." /usr/bin/man ".args."| col -b >
".tmp
silent execute "pedit ".tmp
if !has("gui_running")
redraw!
endif
" Cycle once through windows and set the filetype for
" the newly created preview window. One tab page supports
" only one preview window, so there cannot be any conflicts
" about which window to set as a man page.
for i in range(1, winnr('$'))
if getwinvar(i, '&pvw')
" Pulls in
" * restricted write permissions
" * mappings
" * syntax highlighting.
call setwinvar(i, "&ft", 'man')
endif
endfor
endfunction
function s:PreviewPageUnderCursor()
" Inspects <cword> and calls PreviewPage to view a man
" page. Stack is updated as a side effect if the
" manual page exists.
let old_isk = &iskeyword
setl iskeyword+=(,)
let str = expand("<cword>")
let &l:iskeyword = old_isk
let page = substitute(str, '(*\(\k\+\).*', '\1', '')
let sect = substitute(str, '\(\k\+\)(\([^()]*\)).*', '\2', '')
if match(sect, '^[0-9 ]\+$') == -1
let sect = ""
endif
if sect == page
let sect = ""
endif
try
let jump_info = [{bufnr('%'):winsaveview()}]
call <SID>PreviewPage(sect, page)
catch /IOError/
let jump_info = []
finally
let s:view_stack += jump_info
endtry
endfunction
function s:ManPop()
" Pop the last buffer and view from s:view_stack
" and jump to this buffer and view
if len(s:view_stack) > 0
let jump_to = s:view_stack[-1]
let s:view_stack = s:view_stack[:-2]
execute keys(jump_to)[0].'buffer'
call winrestview(values(jump_to)[0])
" Jumped back to a shell script
if &ft != 'man'
pclose
endif
else
echo "Cannot jump to a previous man page: None present"
endif
return
endfunction
function s:Whatis(topic)
" Display short description of `topic'
if a:topic == '<cword>'
let topic = expand('<cword>')
else
let topic = a:topic
endif
let descr = system("/usr/bin/man -f ".topic)
let descr = substitute(descr, "\n", "", "g")
echo descr
endfunction
function s:WhatisUnderCursor()
let old_isk = &iskeyword
setl iskeyword+=(,)
let str = expand("<cword>")
let &l:iskeyword = old_isk
let page = substitute(str, '(*\(\k\+\).*', '\1', '')
call <SID>Whatis(page)
endfunction
endif
" vim: set sw=4: