aboutsummaryrefslogtreecommitdiff
path: root/misc/vim/plugin/godoc.vim
blob: 5d7ce14ad303b000ae9ab15c02bdccfa0e70c9fa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
" Copyright 2011 The Go Authors. All rights reserved.
" Use of this source code is governed by a BSD-style
" license that can be found in the LICENSE file.
"
" godoc.vim: Vim command to see godoc.

if exists("g:loaded_godoc")
  finish
endif
let g:loaded_godoc = 1

let s:buf_nr = -1
let s:last_word = ''
let s:goos = $GOOS
let s:goarch = $GOARCH

function! s:GodocView()
  if !bufexists(s:buf_nr)
    leftabove new
    file `="[Godoc]"`
    let s:buf_nr = bufnr('%')
  elseif bufwinnr(s:buf_nr) == -1
    leftabove split
    execute s:buf_nr . 'buffer'
    delete _
  elseif bufwinnr(s:buf_nr) != bufwinnr('%')
    execute bufwinnr(s:buf_nr) . 'wincmd w'
  endif

  setlocal filetype=godoc
  setlocal bufhidden=delete
  setlocal buftype=nofile
  setlocal noswapfile
  setlocal nobuflisted
  setlocal modifiable
  setlocal nocursorline
  setlocal nocursorcolumn
  setlocal iskeyword+=:
  setlocal iskeyword-=-

  nnoremap <buffer> <silent> K :Godoc<cr>

  au BufHidden <buffer> call let <SID>buf_nr = -1
endfunction

function! s:GodocWord(word)
  let word = a:word
  silent! let content = system('godoc ' . word)
  if v:shell_error || !len(content)
    if len(s:last_word)
      silent! let content = system('godoc ' . s:last_word.'/'.word)
      if v:shell_error || !len(content)
        echo 'No documentation found for "' . word . '".'
        return
      endif
      let word = s:last_word.'/'.word
    else
      echo 'No documentation found for "' . word . '".'
      return
    endif
  endif
  let s:last_word = word
  silent! call s:GodocView()
  setlocal modifiable
  silent! %d _
  silent! put! =content
  silent! normal gg
  setlocal nomodifiable
  setfiletype godoc
endfunction

function! s:Godoc(...)
  let word = join(a:000, ' ')
  if !len(word)
    let word = expand('<cword>')
  endif
  let word = substitute(word, '[^a-zA-Z0-9\/]', '', 'g')
  if !len(word)
    return
  endif
  call s:GodocWord(word)
endfunction

function! s:GodocComplete(ArgLead, CmdLine, CursorPos)
  if len($GOROOT) == 0
    return []
  endif
  if len(s:goos) == 0
    if exists('g:godoc_goos')
      let s:goos = g:godoc_goos
    elseif has('win32') || has('win64')
      let s:goos = 'windows'
    elseif has('macunix')
      let s:goos = 'darwin'
    else
      let s:goos = '*'
    endif
  endif
  if len(s:goarch) == 0
    if exists('g:godoc_goarch')
      let s:goarch = g:godoc_goarch
    else
      let s:goarch = g:godoc_goarch
    endif
  endif
  let ret = {}
  let root = expand($GOROOT.'/pkg/'.s:goos.'_'.s:goarch)
  for i in split(globpath(root, a:ArgLead.'*'), "\n")
    if isdirectory(i)
      let i .= '/'
    elseif i !~ '\.a$'
      continue
    endif
    let i = substitute(substitute(i[len(root)+1:], '[\\]', '/', 'g'), '\.a$', '', 'g')
    let ret[i] = i
  endfor
  return sort(keys(ret))
endfunction

command! -nargs=* -range -complete=customlist,s:GodocComplete Godoc :call s:Godoc(<q-args>)
nnoremap <silent> <Plug>(godoc-keyword) :<C-u>call <SID>Godoc('')<CR>

" vim:ts=4:sw=4:et