Vim Tips Wiki
(Replaced external links with {{script}} links)
(Proper shellescape)
 
(6 intermediate revisions by 4 users not shown)
Line 11: Line 11:
 
|category2=
 
|category2=
 
}}
 
}}
This tip presents several ways to access Python documentation using <tt>pydoc</tt>. The recommended location for the commands in this snippet is <tt>~/.vim/after/ftplugin/python.vim</tt>, or <tt>$HOME\vimfiles\after\ftplugin\python.vim</tt> on Windows.
+
This tip presents several ways to access Python documentation using <code>pydoc</code>. The recommended location for the commands in this snippet is <code>~/.vim/after/ftplugin/python.vim</code>, or <code>$HOME\vimfiles\after\ftplugin\python.vim</code> on Windows.
   
 
==Using a shell (simple)==
 
==Using a shell (simple)==
 
To access Python documentation for the word under the cursor using, this mapping can be used
 
To access Python documentation for the word under the cursor using, this mapping can be used
 
<pre>
 
<pre>
map <buffer> K :execute "!pydoc " . expand("<cword>")<CR>
+
nnoremap <buffer> K :<C-u>execute "!pydoc " . expand("<cword>")<CR>
 
</pre>
 
</pre>
   
 
or for Windows
 
or for Windows
 
<pre>
 
<pre>
map <buffer> K :execute "!C:/<PythonDir>/Lib/pydoc.py " . expand("<cword>")<CR>
+
nnoremap <buffer> K :<C-u>execute "!C:/<PythonDir>/Lib/pydoc.py " . expand("<cword>")<CR>
 
</pre>
 
</pre>
   
 
To keep the documentation open while you continue editing, this mapping can be used instead
 
To keep the documentation open while you continue editing, this mapping can be used instead
 
<pre>
 
<pre>
map <buffer> K :execute "!xterm -e 'pydoc " . expand("<cword>") . "'"<CR>
+
nnoremap <buffer> K :<C-u>execute "!xterm -e 'pydoc " . expand("<cword>") . "'"<CR>
 
</pre>
 
</pre>
   
 
or for Windows
 
or for Windows
 
<pre>
 
<pre>
map <buffer> K :execute "!start cmd /c C:/<PythonDir>/Lib/pydoc.py " . \|
+
nnoremap <buffer> K :<C-u>execute "!start cmd /c C:/<PythonDir>/Lib/pydoc.py " . \|
 
\ expand("<cword>")<CR>
 
\ expand("<cword>")<CR>
 
</pre>
 
</pre>
   
These mappings only work for single words. To display the documentation for a method or a class in a module, for example <tt>os.popen()</tt>, modify the mapping in this way
+
These mappings only work for single words. To display the documentation for a method or a class in a module, for example <code>os.popen()</code>, modify the mapping in this way
 
<pre>
 
<pre>
map <buffer> K :let save_isk = &iskeyword \|
+
nnoremap <buffer> K :<C-u>let save_isk = &iskeyword \|
 
\ set iskeyword+=. \|
 
\ set iskeyword+=. \|
 
\ execute "!pydoc " . expand("<cword>") \|
 
\ execute "!pydoc " . expand("<cword>") \|
Line 43: Line 43:
 
</pre>
 
</pre>
   
It is '''not recommended''' to permanently add <tt>.</tt> to <tt>'iskeyword'</tt>.
+
It is '''not recommended''' to permanently add <code>.</code> to <code>'iskeyword'</code>.
   
 
==Using the preview window or a scratch buffer==
 
==Using the preview window or a scratch buffer==
This snippet allows you to use the command <tt>:Pyhelp <string></tt> to preview Python documentation in the preview window. It also remaps <tt>K</tt> in the same manner as above.
+
This snippet allows you to use the command <code>:Pyhelp <string></code> to preview Python documentation in the preview window. It also remaps <code>K</code> in the same manner as above.
   
If Vim is compiled with <tt>+python</tt>, it automatically finds the path to <tt>pydoc.py</tt>. Otherwise, set the <tt>s:pydoc_path</tt> variable to a suitable value. This seemingly indirect approach is used in an effort to make the snippet platform agnostic.
+
If Vim is compiled with <code>+python</code>, it automatically finds the path to <code>pydoc.py</code>. Otherwise, set the <code>s:pydoc_path</code> variable to a suitable value. This seemingly indirect approach is used in an effort to make the snippet platform agnostic.
   
 
<pre>
 
<pre>
Line 63: Line 63:
 
endif
 
endif
   
map <buffer> K :let save_isk = &iskeyword \|
+
nnoremap <buffer> K :<C-u>let save_isk = &iskeyword \|
 
\ set iskeyword+=. \|
 
\ set iskeyword+=. \|
 
\ execute "Pyhelp " . expand("<cword>") \|
 
\ execute "Pyhelp " . expand("<cword>") \|
 
\ let &iskeyword = save_isk<CR>
 
\ let &iskeyword = save_isk<CR>
command! -nargs=1 Pyhelp :call ShowPydoc(<f-args>)
+
command! -nargs=1 -bar Pyhelp :call ShowPydoc(<f-args>)
 
function! ShowPydoc(what)
 
function! ShowPydoc(what)
 
" compose a tempfile path using the argument to the function
 
" compose a tempfile path using the argument to the function
 
let path = $TEMP . '/' . a:what . '.pydoc'
 
let path = $TEMP . '/' . a:what . '.pydoc'
  +
let epath = shellescape(path)
  +
let epydoc_path = shellescape(s:pydoc_path)
  +
let ewhat = shellescape(a:what)
 
" run pydoc on the argument, and redirect the output to the tempfile
 
" run pydoc on the argument, and redirect the output to the tempfile
  +
call system(epydoc_path . " " . ewhat . (stridx(&shellredir, '%s') == -1 ? (&shellredir.epath) : (substitute(&shellredir, '\V\C%s', '\=epath', ''))))
call system(shellescape(s:pydoc_path . " " . a:what . " > " . path))
 
 
" open the tempfile in the preview window
 
" open the tempfile in the preview window
execute "pedit " . path
+
execute "pedit" fnameescape(path)
 
endfunction
 
endfunction
 
</pre>
 
</pre>
   
If, instead, you prefer using a scratch buffer to the preview window, change the <tt>ShowPydoc</tt> function to
+
If, instead, you prefer using a scratch buffer to the preview window, change the <code>ShowPydoc</code> function to
   
 
<pre>
 
<pre>
Line 88: Line 91:
 
if winnr != -1
 
if winnr != -1
 
" if the buffer is already displayed, switch to that window
 
" if the buffer is already displayed, switch to that window
execute winnr . "wincmd w"
+
execute winnr "wincmd w"
 
else
 
else
 
" otherwise, open the buffer in a split
 
" otherwise, open the buffer in a split
execute "sbuffer " . bufname
+
execute "sbuffer" bufname
 
endif
 
endif
 
else
 
else
 
" create a new buffer, set the nofile buftype and don't display it in the
 
" create a new buffer, set the nofile buftype and don't display it in the
 
" buffer list
 
" buffer list
execute "split " . bufname
+
execute "split" fnameescape(bufname)
 
setlocal buftype=nofile
 
setlocal buftype=nofile
 
setlocal nobuflisted
 
setlocal nobuflisted
 
" read the output from pydoc
 
" read the output from pydoc
execute "r !" . shellescape(s:pydoc_path . " " . a:what)
+
execute "r !" . shellescape(s:pydoc_path, 1) . " " . shellescape(a:what, 1)
 
endif
 
endif
 
" go to the first line of the document
 
" go to the first line of the document
Line 124: Line 127:
 
==Comments==
 
==Comments==
 
For an alternative approach to the same problem, try the [http://peterodding.com/code/vim/pyref/ pyref.vim plug-in] (
 
For an alternative approach to the same problem, try the [http://peterodding.com/code/vim/pyref/ pyref.vim plug-in] (
{{script|id=3104|text=vimscript #3104}}) which provides context-sensitive documentation for Python source code by looking up help topics on [http://docs.python.org/ docs.python.org] (or a local mirror on your file system) and showing them in your favorite web browser.
+
{{script|id=3104}}) which provides context-sensitive documentation for Python source code by looking up help topics on [http://docs.python.org/ docs.python.org] (or a local mirror on your file system) and showing them in your favorite web browser.

Latest revision as of 07:34, 14 July 2013

Tip 556 Printable Monobook Previous Next

created 2003 · complexity basic · author Fritz Cizmarov · version 6.0


This tip presents several ways to access Python documentation using pydoc. The recommended location for the commands in this snippet is ~/.vim/after/ftplugin/python.vim, or $HOME\vimfiles\after\ftplugin\python.vim on Windows.

Using a shell (simple)[]

To access Python documentation for the word under the cursor using, this mapping can be used

nnoremap <buffer> K :<C-u>execute "!pydoc " . expand("<cword>")<CR>

or for Windows

nnoremap <buffer> K :<C-u>execute "!C:/<PythonDir>/Lib/pydoc.py " . expand("<cword>")<CR>

To keep the documentation open while you continue editing, this mapping can be used instead

nnoremap <buffer> K :<C-u>execute "!xterm -e 'pydoc " . expand("<cword>") . "'"<CR>

or for Windows

nnoremap <buffer> K :<C-u>execute "!start cmd /c C:/<PythonDir>/Lib/pydoc.py " . \|
    \ expand("<cword>")<CR>

These mappings only work for single words. To display the documentation for a method or a class in a module, for example os.popen(), modify the mapping in this way

nnoremap <buffer> K :<C-u>let save_isk = &iskeyword \|
    \ set iskeyword+=. \|
    \ execute "!pydoc " . expand("<cword>") \|
    \ let &iskeyword = save_isk<CR>

It is not recommended to permanently add . to 'iskeyword'.

Using the preview window or a scratch buffer[]

This snippet allows you to use the command :Pyhelp <string> to preview Python documentation in the preview window. It also remaps K in the same manner as above.

If Vim is compiled with +python, it automatically finds the path to pydoc.py. Otherwise, set the s:pydoc_path variable to a suitable value. This seemingly indirect approach is used in an effort to make the snippet platform agnostic.

if has("python")
  " let python figure out the path to pydoc
  python << EOF
import sys
import vim
vim.command("let s:pydoc_path=\'" + sys.prefix + "/lib/pydoc.py\'")
EOF
else
  " manually set the path to pydoc
  let s:pydoc_path = "/path/to/python/lib/pydoc.py"
endif

nnoremap <buffer> K :<C-u>let save_isk = &iskeyword \|
    \ set iskeyword+=. \|
    \ execute "Pyhelp " . expand("<cword>") \|
    \ let &iskeyword = save_isk<CR>
command! -nargs=1 -bar Pyhelp :call ShowPydoc(<f-args>)
function! ShowPydoc(what)
  " compose a tempfile path using the argument to the function
  let path = $TEMP . '/' . a:what . '.pydoc'
  let epath = shellescape(path)
  let epydoc_path = shellescape(s:pydoc_path)
  let ewhat = shellescape(a:what)
  " run pydoc on the argument, and redirect the output to the tempfile
  call system(epydoc_path . " " . ewhat . (stridx(&shellredir, '%s') == -1 ? (&shellredir.epath) : (substitute(&shellredir, '\V\C%s', '\=epath', ''))))
  " open the tempfile in the preview window
  execute "pedit" fnameescape(path)
endfunction

If, instead, you prefer using a scratch buffer to the preview window, change the ShowPydoc function to

function! ShowPydoc(what)
  let bufname = a:what . ".pydoc"
  " check if the buffer exists already
  if bufexists(bufname)
    let winnr = bufwinnr(bufname)
    if winnr != -1
      " if the buffer is already displayed, switch to that window
      execute winnr "wincmd w"
    else
      " otherwise, open the buffer in a split
      execute "sbuffer" bufname
    endif
  else
    " create a new buffer, set the nofile buftype and don't display it in the
    " buffer list
    execute "split" fnameescape(bufname)
    setlocal buftype=nofile
    setlocal nobuflisted
    " read the output from pydoc
    execute "r !" . shellescape(s:pydoc_path, 1) . " " . shellescape(a:what, 1)
  endif
  " go to the first line of the document
  1
endfunction

See also[]

References[]

Comments[]

For an alternative approach to the same problem, try the pyref.vim plug-in ( script#3104) which provides context-sensitive documentation for Python source code by looking up help topics on docs.python.org (or a local mirror on your file system) and showing them in your favorite web browser.