github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/tools/cmd/oracle/oracle.vim (about)

     1  " -*- text -*-
     2  "  oracle.vim -- Vim integration for the Go oracle.
     3  "
     4  "  Load with (e.g.)  :source oracle.vim
     5  "  Call with (e.g.)  :GoOracleDescribe
     6  "  while cursor or selection is over syntax of interest.
     7  "  Run :copen to show the quick-fix file.
     8  "
     9  " This is an absolutely rudimentary integration of the Go Oracle into
    10  " Vim's quickfix mechanism and it needs a number of usability
    11  " improvements before it can be practically useful to Vim users.
    12  " Voluntary contributions welcomed!
    13  "
    14  " TODO(adonovan):
    15  " - reject buffers with no filename.
    16  " - hide all filenames in quickfix buffer.
    17  
    18  " Get the path to the Go oracle executable.
    19  func! s:go_oracle_bin()
    20    let [ext, sep] = (has('win32') || has('win64') ? ['.exe', ';'] : ['', ':'])
    21    let go_oracle = globpath(join(split($GOPATH, sep), ','), '/bin/oracle' . ext)
    22    if go_oracle == ''
    23      let go_oracle = globpath($GOROOT, '/bin/oracle' . ext)
    24    endif
    25    return go_oracle
    26  endfunction
    27  
    28  let s:go_oracle = s:go_oracle_bin()
    29  
    30  func! s:qflist(output)
    31    let qflist = []
    32    " Parse GNU-style 'file:line.col-line.col: message' format.
    33    let mx = '^\(\a:[\\/][^:]\+\|[^:]\+\):\(\d\+\):\(\d\+\):\(.*\)$'
    34    for line in split(a:output, "\n")
    35      let ml = matchlist(line, mx)
    36      " Ignore non-match lines or warnings
    37      if ml == [] || ml[4] =~ '^ warning:'
    38        continue
    39      endif
    40      let item = {
    41      \  'filename': ml[1],
    42      \  'text': ml[4],
    43      \  'lnum': ml[2],
    44      \  'col': ml[3],
    45      \}
    46      let bnr = bufnr(fnameescape(ml[1]))
    47      if bnr != -1
    48        let item['bufnr'] = bnr
    49      endif
    50      call add(qflist, item)
    51    endfor
    52    call setqflist(qflist)
    53    cwindow
    54  endfun
    55  
    56  func! s:getpos(l, c)
    57    if &encoding != 'utf-8'
    58      let buf = a:l == 1 ? '' : (join(getline(1, a:l-1), "\n") . "\n")
    59      let buf .= a:c == 1 ? '' : getline('.')[:a:c-2]
    60      return len(iconv(buf, &encoding, 'utf-8'))
    61    endif
    62    return line2byte(a:l) + (a:c-2)
    63  endfun
    64  
    65  func! s:RunOracle(mode, selected) range abort
    66    let fname = expand('%:p')
    67    let sname = get(g:, 'go_oracle_scope_file', fname)
    68    if a:selected != -1
    69      let pos1 = s:getpos(line("'<"), col("'<"))
    70      let pos2 = s:getpos(line("'>"), col("'>"))
    71      let cmd = printf('%s -pos=%s:#%d,#%d %s %s',
    72        \  s:go_oracle,
    73        \  shellescape(fname), pos1, pos2, a:mode, shellescape(sname))
    74    else
    75      let pos = s:getpos(line('.'), col('.'))
    76      let cmd = printf('%s -pos=%s:#%d %s %s',
    77        \  s:go_oracle,
    78        \  shellescape(fname), pos, a:mode, shellescape(sname))
    79    endif
    80    call s:qflist(system(cmd))
    81  endfun
    82  
    83  " Describe the expression at the current point.
    84  command! -range=% GoOracleDescribe
    85    \ call s:RunOracle('describe', <count>)
    86  
    87  " Show possible callees of the function call at the current point.
    88  command! -range=% GoOracleCallees
    89    \ call s:RunOracle('callees', <count>)
    90  
    91  " Show the set of callers of the function containing the current point.
    92  command! -range=% GoOracleCallers
    93    \ call s:RunOracle('callers', <count>)
    94  
    95  " Show the callgraph of the current program.
    96  command! -range=% GoOracleCallgraph
    97    \ call s:RunOracle('callgraph', <count>)
    98  
    99  " Describe the 'implements' relation for types in the
   100  " package containing the current point.
   101  command! -range=% GoOracleImplements
   102    \ call s:RunOracle('implements', <count>)
   103  
   104  " Enumerate the set of possible corresponding sends/receives for
   105  " this channel receive/send operation.
   106  command! -range=% GoOracleChannelPeers
   107    \ call s:RunOracle('peers', <count>)