mirror of
https://github.com/amix/vimrc
synced 2025-06-16 01:25:00 +08:00
Updated plugins
This commit is contained in:
@ -87,8 +87,8 @@ function! ctrlp#decls#enter()
|
||||
let command .= printf(" -dir %s", dir)
|
||||
endif
|
||||
|
||||
let out = system(command)
|
||||
if v:shell_error != 0
|
||||
let out = go#util#System(command)
|
||||
if go#util#ShellError() != 0
|
||||
call go#util#EchoError(out)
|
||||
return
|
||||
endif
|
||||
|
@ -32,10 +32,10 @@ function! go#asmfmt#Format()
|
||||
if empty(path)
|
||||
return
|
||||
endif
|
||||
let out = system(path . ' -w ' . l:tmpname)
|
||||
let out = go#util#System(path . ' -w ' . l:tmpname)
|
||||
|
||||
" If there's no error, replace the current file with the output.
|
||||
if v:shell_error == 0
|
||||
if go#util#ShellError() == 0
|
||||
" Remove undo point caused by BufWritePre.
|
||||
try | silent undojoin | catch | endtry
|
||||
|
||||
|
@ -229,7 +229,7 @@ function! go#cmd#Test(bang, compile, ...)
|
||||
|
||||
let l:listtype = "quickfix"
|
||||
|
||||
if v:shell_error
|
||||
if go#util#ShellError() != 0
|
||||
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
|
||||
let dir = getcwd()
|
||||
try
|
||||
@ -272,7 +272,7 @@ function! go#cmd#TestFunc(bang, ...)
|
||||
"
|
||||
" for the full list
|
||||
" :help search
|
||||
let test = search("func Test", "bcnW")
|
||||
let test = search('func \(Test\|Example\)', "bcnW")
|
||||
|
||||
if test == 0
|
||||
echo "vim-go: [test] no test found immediate to cursor"
|
||||
@ -299,7 +299,7 @@ function! go#cmd#Generate(bang, ...)
|
||||
|
||||
" :make expands '%' and '#' wildcards, so they must also be escaped
|
||||
let goargs = go#util#Shelljoin(map(copy(a:000), "expand(v:val)"), 1)
|
||||
if v:shell_error
|
||||
if go#util#ShellError() != 0
|
||||
let &makeprg = "go generate " . goargs
|
||||
else
|
||||
let gofiles = go#util#Shelljoin(go#tool#Files(), 1)
|
||||
|
@ -19,44 +19,12 @@ fu! s:gocodeCurrentBuffer()
|
||||
return file
|
||||
endf
|
||||
|
||||
if go#vimproc#has_vimproc()
|
||||
let s:vim_system = get(g:, 'gocomplete#system_function', 'vimproc#system2')
|
||||
let s:vim_shell_error = get(g:, 'gocomplete#shell_error_function', 'vimproc#get_last_status')
|
||||
else
|
||||
let s:vim_system = get(g:, 'gocomplete#system_function', 'system')
|
||||
let s:vim_shell_error = ''
|
||||
endif
|
||||
|
||||
fu! s:shell_error()
|
||||
if empty(s:vim_shell_error)
|
||||
return v:shell_error
|
||||
endif
|
||||
return call(s:vim_shell_error, [])
|
||||
endf
|
||||
|
||||
fu! s:system(str, ...)
|
||||
return call(s:vim_system, [a:str] + a:000)
|
||||
endf
|
||||
|
||||
fu! s:gocodeShellescape(arg)
|
||||
if go#vimproc#has_vimproc()
|
||||
return vimproc#shellescape(a:arg)
|
||||
endif
|
||||
try
|
||||
let ssl_save = &shellslash
|
||||
set noshellslash
|
||||
return shellescape(a:arg)
|
||||
finally
|
||||
let &shellslash = ssl_save
|
||||
endtry
|
||||
endf
|
||||
|
||||
fu! s:gocodeCommand(cmd, preargs, args)
|
||||
for i in range(0, len(a:args) - 1)
|
||||
let a:args[i] = s:gocodeShellescape(a:args[i])
|
||||
let a:args[i] = go#util#Shellescape(a:args[i])
|
||||
endfor
|
||||
for i in range(0, len(a:preargs) - 1)
|
||||
let a:preargs[i] = s:gocodeShellescape(a:preargs[i])
|
||||
let a:preargs[i] = go#util#Shellescape(a:preargs[i])
|
||||
endfor
|
||||
|
||||
let bin_path = go#path#CheckBinPath(g:go_gocode_bin)
|
||||
@ -69,11 +37,11 @@ fu! s:gocodeCommand(cmd, preargs, args)
|
||||
let old_gopath = $GOPATH
|
||||
let $GOPATH = go#path#Detect()
|
||||
|
||||
let result = s:system(printf('%s %s %s %s', s:gocodeShellescape(bin_path), join(a:preargs), s:gocodeShellescape(a:cmd), join(a:args)))
|
||||
let result = go#util#System(printf('%s %s %s %s', go#util#Shellescape(bin_path), join(a:preargs), go#util#Shellescape(a:cmd), join(a:args)))
|
||||
|
||||
let $GOPATH = old_gopath
|
||||
|
||||
if s:shell_error() != 0
|
||||
if go#util#ShellError() != 0
|
||||
return "[\"0\", []]"
|
||||
else
|
||||
if &encoding != 'utf-8'
|
||||
|
@ -1,16 +1,35 @@
|
||||
let s:toggle = 0
|
||||
|
||||
" Buffer creates a new cover profile with 'go test -coverprofile' and changes
|
||||
" teh current buffers highlighting to show covered and uncovered sections of
|
||||
" the code. If run again it clears the annotation
|
||||
function! go#coverage#Buffer(bang, ...)
|
||||
" the current buffers highlighting to show covered and uncovered sections of
|
||||
" the code. If run again it clears the annotation.
|
||||
function! go#coverage#BufferToggle(bang, ...)
|
||||
if s:toggle
|
||||
call go#coverage#Clear()
|
||||
return
|
||||
endif
|
||||
|
||||
if a:0 == 0
|
||||
return call(function('go#coverage#Buffer'), [a:bang])
|
||||
endif
|
||||
|
||||
return call(function('go#coverage#Buffer'), [a:bang] + a:000)
|
||||
endfunction
|
||||
|
||||
" Buffer creates a new cover profile with 'go test -coverprofile' and changes
|
||||
" teh current buffers highlighting to show covered and uncovered sections of
|
||||
" the code. Calling it again reruns the tests and shows the last updated
|
||||
" coverage.
|
||||
function! go#coverage#Buffer(bang, ...)
|
||||
" we use matchaddpos() which was introduce with 7.4.330, be sure we have
|
||||
" it: http://ftp.vim.org/vim/patches/7.4/7.4.330
|
||||
if !exists("*matchaddpos")
|
||||
call go#util#EchoError("GoCoverage is supported with Vim version 7.4-330 or later")
|
||||
return -1
|
||||
endif
|
||||
|
||||
let s:toggle = 1
|
||||
let l:tmpname=tempname()
|
||||
let l:tmpname = tempname()
|
||||
let args = [a:bang, 0, "-coverprofile", l:tmpname]
|
||||
|
||||
if a:0
|
||||
@ -35,7 +54,7 @@ function! go#coverage#Buffer(bang, ...)
|
||||
return
|
||||
endif
|
||||
|
||||
if !v:shell_error
|
||||
if go#util#ShellError() == 0
|
||||
call go#coverage#overlay(l:tmpname)
|
||||
endif
|
||||
|
||||
@ -44,7 +63,10 @@ endfunction
|
||||
|
||||
" Clear clears and resets the buffer annotation matches
|
||||
function! go#coverage#Clear()
|
||||
if exists("g:syntax_on") | syntax enable | endif
|
||||
" only reset the syntax if the user has syntax enabled
|
||||
if !empty(&syntax)
|
||||
if exists("g:syntax_on") | syntax enable | endif
|
||||
endif
|
||||
|
||||
if exists("s:toggle") | let s:toggle = 0 | endif
|
||||
|
||||
@ -59,7 +81,7 @@ endfunction
|
||||
" Browser creates a new cover profile with 'go test -coverprofile' and opens
|
||||
" a new HTML coverage page from that profile in a new browser
|
||||
function! go#coverage#Browser(bang, ...)
|
||||
let l:tmpname=tempname()
|
||||
let l:tmpname = tempname()
|
||||
let args = [a:bang, 0, "-coverprofile", l:tmpname]
|
||||
|
||||
if a:0
|
||||
@ -71,7 +93,7 @@ function! go#coverage#Browser(bang, ...)
|
||||
let s:coverage_browser_handler_jobs[id] = l:tmpname
|
||||
return
|
||||
endif
|
||||
if !v:shell_error
|
||||
if go#util#ShellError() == 0
|
||||
let openHTML = 'go tool cover -html='.l:tmpname
|
||||
call go#tool#ExecuteInDir(openHTML)
|
||||
endif
|
||||
|
@ -1,26 +1,8 @@
|
||||
if !exists("g:go_godef_bin")
|
||||
let g:go_godef_bin = "godef"
|
||||
endif
|
||||
let s:go_stack = []
|
||||
let s:go_stack_level = 0
|
||||
|
||||
if go#vimproc#has_vimproc()
|
||||
let s:vim_system = get(g:, 'gocomplete#system_function', 'vimproc#system2')
|
||||
else
|
||||
let s:vim_system = get(g:, 'gocomplete#system_function', 'system')
|
||||
endif
|
||||
|
||||
fu! s:system(str, ...)
|
||||
return call(s:vim_system, [a:str] + a:000)
|
||||
endf
|
||||
|
||||
" modified and improved version of vim-godef
|
||||
function! go#def#Jump(...)
|
||||
if !len(a:000)
|
||||
let arg = "-o=" . go#util#OffsetCursor()
|
||||
else
|
||||
let arg = a:1
|
||||
endif
|
||||
|
||||
let bin_path = go#path#CheckBinPath(g:go_godef_bin)
|
||||
function! go#def#Jump(mode)
|
||||
let bin_path = go#path#CheckBinPath("guru")
|
||||
if empty(bin_path)
|
||||
return
|
||||
endif
|
||||
@ -28,233 +10,193 @@ function! go#def#Jump(...)
|
||||
let old_gopath = $GOPATH
|
||||
let $GOPATH = go#path#Detect()
|
||||
|
||||
let flags = ""
|
||||
if exists('g:go_guru_tags')
|
||||
let tags = get(g:, 'go_guru_tags')
|
||||
let flags = printf(" -tags %s", tags)
|
||||
endif
|
||||
|
||||
let fname = fnamemodify(expand("%"), ':p:gs?\\?/?')
|
||||
let command = bin_path . " -t -f=" . shellescape(fname) . " -i " . shellescape(arg)
|
||||
let command = printf("%s %s definition %s:#%s", bin_path, flags, shellescape(fname), go#util#OffsetCursor())
|
||||
|
||||
" get output of godef
|
||||
let out = s:system(command, join(getbufline(bufnr('%'), 1, '$'), go#util#LineEnding()))
|
||||
|
||||
" First line is <file>:<line>:<col>
|
||||
" Second line is <identifier><space><type>
|
||||
let godefout=split(out, go#util#LineEnding())
|
||||
|
||||
" jump to it
|
||||
call s:godefJump(godefout, "")
|
||||
let $GOPATH = old_gopath
|
||||
endfunction
|
||||
|
||||
|
||||
function! go#def#JumpMode(mode)
|
||||
let arg = "-o=" . go#util#OffsetCursor()
|
||||
|
||||
let bin_path = go#path#CheckBinPath(g:go_godef_bin)
|
||||
if empty(bin_path)
|
||||
let out = go#util#System(command)
|
||||
if go#util#ShellError() != 0
|
||||
call go#util#EchoError(out)
|
||||
return
|
||||
endif
|
||||
|
||||
let old_gopath = $GOPATH
|
||||
let $GOPATH = go#path#Detect()
|
||||
|
||||
let fname = fnamemodify(expand("%"), ':p:gs?\\?/?')
|
||||
let command = bin_path . " -t -f=" . shellescape(fname) . " -i " . shellescape(arg)
|
||||
|
||||
" get output of godef
|
||||
let out = s:system(command, join(getbufline(bufnr('%'), 1, '$'), go#util#LineEnding()))
|
||||
|
||||
" First line is <file>:<line>:<col>
|
||||
" Second line is <identifier><space><type>
|
||||
let godefout=split(out, go#util#LineEnding())
|
||||
|
||||
" jump to it
|
||||
call s:godefJump(godefout, a:mode)
|
||||
call s:jump_to_declaration(out, a:mode)
|
||||
let $GOPATH = old_gopath
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:getOffset()
|
||||
return "-o=" . go#util#OffsetCursor()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:godefJump(out, mode)
|
||||
let old_errorformat = &errorformat
|
||||
let &errorformat = "%f:%l:%c"
|
||||
|
||||
" Location is the first line of godef output. Ideally in the proper format
|
||||
" but it could also be an error
|
||||
let location = a:out[0]
|
||||
|
||||
" Echo the godef error if we had one.
|
||||
if location =~ 'godef: '
|
||||
let gderr=substitute(location, go#util#LineEnding() . '$', '', '')
|
||||
call go#util#EchoError(gderr)
|
||||
return
|
||||
endif
|
||||
|
||||
let parts = split(a:out[0], ':')
|
||||
|
||||
" parts[0] contains filename
|
||||
let fileName = parts[0]
|
||||
|
||||
" Don't jump if it's the same identifier we just jumped to
|
||||
if len(w:go_stack) > 0 && w:go_stack[w:go_stack_level-1]['ident'] == a:out[1] && w:go_stack[w:go_stack_level-1]['file'] == fileName
|
||||
return
|
||||
endif
|
||||
|
||||
" needed for restoring back user setting this is because there are two
|
||||
" modes of switchbuf which we need based on the split mode
|
||||
let old_switchbuf = &switchbuf
|
||||
|
||||
if a:mode == "tab"
|
||||
let &switchbuf = "usetab"
|
||||
|
||||
if bufloaded(fileName) == 0
|
||||
tab split
|
||||
endif
|
||||
elseif a:mode == "split"
|
||||
split
|
||||
elseif a:mode == "vsplit"
|
||||
vsplit
|
||||
else
|
||||
" Don't jump in this window if it's been modified
|
||||
if getbufvar(bufnr('%'), "&mod")
|
||||
call go#util#EchoError("No write since last change")
|
||||
return
|
||||
endif
|
||||
endif
|
||||
|
||||
let stack_entry = {'line': line("."), 'col': col("."),
|
||||
\'file': expand('%:p'), 'ident': a:out[1]}
|
||||
|
||||
" jump to file now
|
||||
call s:goToFileLocation(location)
|
||||
"
|
||||
" Remove anything newer than the current position, just like basic
|
||||
" vim tag support
|
||||
if w:go_stack_level == 0
|
||||
let w:go_stack = []
|
||||
else
|
||||
let w:go_stack = w:go_stack[0:w:go_stack_level-1]
|
||||
endif
|
||||
|
||||
" increment the stack counter
|
||||
let w:go_stack_level += 1
|
||||
|
||||
" push it on to the jumpstack
|
||||
call add(w:go_stack, stack_entry)
|
||||
|
||||
let &switchbuf = old_switchbuf
|
||||
endfunction
|
||||
|
||||
function! go#def#StackUI()
|
||||
if len(w:go_stack) == 0
|
||||
call go#util#EchoError("godef stack empty")
|
||||
return
|
||||
endif
|
||||
|
||||
let stackOut = ['" <Up>,<Down>:navigate <Enter>:jump <Esc>,q:exit']
|
||||
|
||||
let i = 0
|
||||
while i < len(w:go_stack)
|
||||
let entry = w:go_stack[i]
|
||||
let prefix = ""
|
||||
if i == w:go_stack_level
|
||||
let prefix = ">"
|
||||
else
|
||||
let prefix = " "
|
||||
endif
|
||||
call add(stackOut, printf("%s %d %s|%d col %d|%s", prefix, i+1, entry["file"], entry["line"], entry["col"], entry["ident"]))
|
||||
let i += 1
|
||||
endwhile
|
||||
if w:go_stack_level == i
|
||||
call add(stackOut, "> ")
|
||||
endif
|
||||
|
||||
call go#ui#OpenWindow("GoDef Stack", stackOut, "godefstack")
|
||||
noremap <buffer> <silent> <CR> :<C-U>call go#def#SelectStackEntry()<CR>
|
||||
noremap <buffer> <silent> <Esc> :<C-U>call go#ui#CloseWindow()<CR>
|
||||
noremap <buffer> <silent> q :<C-U>call go#ui#CloseWindow()<CR>
|
||||
endfunction
|
||||
|
||||
function! go#def#StackPop(...)
|
||||
if len(w:go_stack) == 0
|
||||
call go#util#EchoError("godef stack empty")
|
||||
return
|
||||
endif
|
||||
if w:go_stack_level == 0
|
||||
call go#util#EchoError("at bottom of the godef stack")
|
||||
return
|
||||
endif
|
||||
if !len(a:000)
|
||||
let numPop = 1
|
||||
else
|
||||
let numPop = a:1
|
||||
endif
|
||||
let newLevel = str2nr(w:go_stack_level) - str2nr(numPop)
|
||||
call go#def#StackJump(newLevel + 1)
|
||||
endfunction
|
||||
|
||||
function! go#def#StackJump(...)
|
||||
if len(w:go_stack) == 0
|
||||
call go#util#EchoError("godef stack empty")
|
||||
return
|
||||
endif
|
||||
if !len(a:000)
|
||||
" Display interactive stack
|
||||
call go#def#StackUI()
|
||||
return
|
||||
function! s:jump_to_declaration(out, mode)
|
||||
" strip line ending
|
||||
let out = split(a:out, go#util#LineEnding())[0]
|
||||
if go#util#IsWin()
|
||||
let parts = split(out, '\(^[a-zA-Z]\)\@<!:')
|
||||
else
|
||||
let jumpTarget= a:1
|
||||
let parts = split(out, ':')
|
||||
endif
|
||||
|
||||
if jumpTarget !~ '^\d\+$'
|
||||
if jumpTarget !~ '^\s*$'
|
||||
call go#util#EchoError("location must be a number")
|
||||
endif
|
||||
return
|
||||
endif
|
||||
let filename = parts[0]
|
||||
let line = parts[1]
|
||||
let col = parts[2]
|
||||
let ident = parts[3]
|
||||
|
||||
let jumpTarget=str2nr(jumpTarget) - 1
|
||||
if jumpTarget >= 0 && jumpTarget < len(w:go_stack)
|
||||
let w:go_stack_level = jumpTarget
|
||||
let target = w:go_stack[w:go_stack_level]
|
||||
" Remove anything newer than the current position, just like basic
|
||||
" vim tag support
|
||||
if s:go_stack_level == 0
|
||||
let s:go_stack = []
|
||||
else
|
||||
let s:go_stack = s:go_stack[0:s:go_stack_level-1]
|
||||
endif
|
||||
|
||||
" jump
|
||||
call s:goToFileLocation(target["file"], target["line"], target["col"])
|
||||
else
|
||||
call go#util#EchoError("invalid godef stack location. Try :GoDefJump to see the list of valid entries")
|
||||
endif
|
||||
endfunction
|
||||
" increment the stack counter
|
||||
let s:go_stack_level += 1
|
||||
|
||||
function! s:goToFileLocation(...)
|
||||
let old_errorformat = &errorformat
|
||||
let &errorformat = "%f:%l:%c"
|
||||
" push it on to the jumpstack
|
||||
let stack_entry = {'line': line("."), 'col': col("."), 'file': expand('%:p'), 'ident': ident}
|
||||
call add(s:go_stack, stack_entry)
|
||||
|
||||
" put the error format into location list so we can jump automatically to
|
||||
" it
|
||||
if a:0 == 3
|
||||
lgetexpr printf("%s:%s:%s", a:1, a:2, a:3)
|
||||
elseif a:0 == 1
|
||||
lgetexpr a:1
|
||||
else
|
||||
lgetexpr ""
|
||||
endif
|
||||
" needed for restoring back user setting this is because there are two
|
||||
" modes of switchbuf which we need based on the split mode
|
||||
let old_switchbuf = &switchbuf
|
||||
|
||||
sil ll 1
|
||||
normal zz
|
||||
" jump to existing buffer if, 1. we have enabled it, 2. the buffer is loaded
|
||||
" and 3. there is buffer window number we switch to
|
||||
if get(g:, 'go_def_reuse_buffer', 0) && bufloaded(filename) != 0 && bufwinnr(filename) != -1
|
||||
" jumpt to existing buffer if it exists
|
||||
execute bufwinnr(filename) . 'wincmd w'
|
||||
elseif a:mode == "tab"
|
||||
let &switchbuf = "usetab"
|
||||
if bufloaded(filename) == 0
|
||||
tab split
|
||||
endif
|
||||
elseif a:mode == "split"
|
||||
split
|
||||
elseif a:mode == "vsplit"
|
||||
vsplit
|
||||
endif
|
||||
|
||||
let &errorformat = old_errorformat
|
||||
" open the file and jump to line and column
|
||||
exec 'edit '.filename
|
||||
call cursor(line, col)
|
||||
|
||||
" also align the line to middle of the view
|
||||
normal! zz
|
||||
|
||||
let &switchbuf = old_switchbuf
|
||||
endfunction
|
||||
|
||||
function! go#def#SelectStackEntry()
|
||||
let target_window = go#ui#GetReturnWindow()
|
||||
if empty(target_window)
|
||||
let target_window = winnr()
|
||||
endif
|
||||
let highlighted_stack_entry = matchstr(getline("."), '^..\zs\(\d\+\)')
|
||||
if !empty(highlighted_stack_entry)
|
||||
execute target_window . "wincmd w"
|
||||
call go#def#StackJump(str2nr(highlighted_stack_entry))
|
||||
endif
|
||||
call go#ui#CloseWindow()
|
||||
let target_window = go#ui#GetReturnWindow()
|
||||
if empty(target_window)
|
||||
let target_window = winnr()
|
||||
endif
|
||||
|
||||
let highlighted_stack_entry = matchstr(getline("."), '^..\zs\(\d\+\)')
|
||||
if !empty(highlighted_stack_entry)
|
||||
execute target_window . "wincmd w"
|
||||
call go#def#Stack(str2nr(highlighted_stack_entry))
|
||||
endif
|
||||
|
||||
call go#ui#CloseWindow()
|
||||
endfunction
|
||||
|
||||
function! go#def#StackUI()
|
||||
if len(s:go_stack) == 0
|
||||
call go#util#EchoError("godef stack empty")
|
||||
return
|
||||
endif
|
||||
|
||||
let stackOut = ['" <Up>,<Down>:navigate <Enter>:jump <Esc>,q:exit']
|
||||
|
||||
let i = 0
|
||||
while i < len(s:go_stack)
|
||||
let entry = s:go_stack[i]
|
||||
let prefix = ""
|
||||
|
||||
if i == s:go_stack_level
|
||||
let prefix = ">"
|
||||
else
|
||||
let prefix = " "
|
||||
endif
|
||||
|
||||
call add(stackOut, printf("%s %d %s|%d col %d|%s",
|
||||
\ prefix, i+1, entry["file"], entry["line"], entry["col"], entry["ident"]))
|
||||
let i += 1
|
||||
endwhile
|
||||
|
||||
if s:go_stack_level == i
|
||||
call add(stackOut, "> ")
|
||||
endif
|
||||
|
||||
call go#ui#OpenWindow("GoDef Stack", stackOut, "godefstack")
|
||||
|
||||
noremap <buffer> <silent> <CR> :<C-U>call go#def#SelectStackEntry()<CR>
|
||||
noremap <buffer> <silent> <Esc> :<C-U>call go#ui#CloseWindow()<CR>
|
||||
noremap <buffer> <silent> q :<C-U>call go#ui#CloseWindow()<CR>
|
||||
endfunction
|
||||
|
||||
function! go#def#StackClear(...)
|
||||
let s:go_stack = []
|
||||
let s:go_stack_level = 0
|
||||
endfunction
|
||||
|
||||
function! go#def#StackPop(...)
|
||||
if len(s:go_stack) == 0
|
||||
call go#util#EchoError("godef stack empty")
|
||||
return
|
||||
endif
|
||||
|
||||
if s:go_stack_level == 0
|
||||
call go#util#EchoError("at bottom of the godef stack")
|
||||
return
|
||||
endif
|
||||
|
||||
if !len(a:000)
|
||||
let numPop = 1
|
||||
else
|
||||
let numPop = a:1
|
||||
endif
|
||||
|
||||
let newLevel = str2nr(s:go_stack_level) - str2nr(numPop)
|
||||
call go#def#Stack(newLevel + 1)
|
||||
endfunction
|
||||
|
||||
function! go#def#Stack(...)
|
||||
if len(s:go_stack) == 0
|
||||
call go#util#EchoError("godef stack empty")
|
||||
return
|
||||
endif
|
||||
|
||||
if !len(a:000)
|
||||
" Display interactive stack
|
||||
call go#def#StackUI()
|
||||
return
|
||||
else
|
||||
let jumpTarget = a:1
|
||||
endif
|
||||
|
||||
if jumpTarget !~ '^\d\+$'
|
||||
if jumpTarget !~ '^\s*$'
|
||||
call go#util#EchoError("location must be a number")
|
||||
endif
|
||||
return
|
||||
endif
|
||||
|
||||
let jumpTarget = str2nr(jumpTarget) - 1
|
||||
|
||||
if jumpTarget >= 0 && jumpTarget < len(s:go_stack)
|
||||
let s:go_stack_level = jumpTarget
|
||||
let target = s:go_stack[s:go_stack_level]
|
||||
|
||||
" jump
|
||||
exec 'edit '.target["file"]
|
||||
call cursor(target["line"], target["col"])
|
||||
normal! zz
|
||||
else
|
||||
call go#util#EchoError("invalid location. Try :GoDefStack to see the list of valid entries")
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
@ -88,8 +88,8 @@ function! go#doc#Open(newmode, mode, ...)
|
||||
|
||||
let command = printf("%s -pos %s:#%s", bin_path, fname, offset)
|
||||
|
||||
let out = system(command)
|
||||
if v:shell_error != 0
|
||||
let out = go#util#System(command)
|
||||
if go#util#ShellError() != 0
|
||||
call go#util#EchoError(out)
|
||||
return
|
||||
endif
|
||||
|
@ -65,11 +65,11 @@ function! go#fmt#Format(withGoimport)
|
||||
try
|
||||
mkview!
|
||||
catch
|
||||
let l:curw=winsaveview()
|
||||
let l:curw = winsaveview()
|
||||
endtry
|
||||
else
|
||||
" Save cursor position and many other things.
|
||||
let l:curw=winsaveview()
|
||||
let l:curw = winsaveview()
|
||||
endif
|
||||
|
||||
" Write current unsaved buffer to a temp file
|
||||
@ -81,7 +81,7 @@ function! go#fmt#Format(withGoimport)
|
||||
" prevent an additional undo jump due to BufWritePre auto command and also
|
||||
" restore 'redo' history because it's getting being destroyed every
|
||||
" BufWritePre
|
||||
let tmpundofile=tempname()
|
||||
let tmpundofile = tempname()
|
||||
exe 'wundo! ' . tmpundofile
|
||||
endif
|
||||
|
||||
@ -115,7 +115,7 @@ function! go#fmt#Format(withGoimport)
|
||||
|
||||
if fmt_command == "goimports"
|
||||
if !exists('b:goimports_vendor_compatible')
|
||||
let out = system("goimports --help")
|
||||
let out = go#util#System("goimports --help")
|
||||
if out !~ "-srcdir"
|
||||
echohl WarningMsg
|
||||
echomsg "vim-go: goimports does not support srcdir."
|
||||
@ -135,7 +135,10 @@ function! go#fmt#Format(withGoimport)
|
||||
endif
|
||||
|
||||
" execute our command...
|
||||
let out = system(command . " " . l:tmpname)
|
||||
if go#util#IsWin()
|
||||
let l:tmpname = tr(l:tmpname, '\', '/')
|
||||
endif
|
||||
let out = go#util#System(command . " " . l:tmpname)
|
||||
|
||||
if fmt_command != "gofmt"
|
||||
let $GOPATH = old_gopath
|
||||
@ -145,7 +148,7 @@ function! go#fmt#Format(withGoimport)
|
||||
"if there is no error on the temp file replace the output with the current
|
||||
"file (if this fails, we can always check the outputs first line with:
|
||||
"splitted =~ 'package \w\+')
|
||||
if v:shell_error == 0
|
||||
if go#util#ShellError() == 0
|
||||
" remove undo point caused via BufWritePre
|
||||
try | silent undojoin | catch | endtry
|
||||
|
||||
|
303
sources_non_forked/vim-go/autoload/go/guru.vim
Normal file
303
sources_non_forked/vim-go/autoload/go/guru.vim
Normal file
@ -0,0 +1,303 @@
|
||||
" guru.vim -- Vim integration for the Go guru.
|
||||
|
||||
func! s:RunGuru(mode, format, selected, needs_scope) range abort
|
||||
"return with a warning if the binary doesn't exist
|
||||
let bin_path = go#path#CheckBinPath("guru")
|
||||
if empty(bin_path)
|
||||
return {'err': "bin path not found"}
|
||||
endif
|
||||
|
||||
let filename = expand('%:p')
|
||||
let dirname = expand('%:p:h')
|
||||
let pkg = go#package#ImportPath(dirname)
|
||||
|
||||
" this is important, check it!
|
||||
if pkg == -1 && a:needs_scope
|
||||
return {'err': "current directory is not inside of a valid GOPATH"}
|
||||
endif
|
||||
|
||||
" start constructing the 'command' variable
|
||||
let command = bin_path
|
||||
|
||||
" enable outputting in json format
|
||||
if a:format == "json"
|
||||
let command .= " -json"
|
||||
endif
|
||||
|
||||
" check for any tags
|
||||
if exists('g:go_guru_tags')
|
||||
let tags = get(g:, 'go_guru_tags')
|
||||
let command .= printf(" -tags %s", tags)
|
||||
endif
|
||||
|
||||
" some modes require scope to be defined (such as callers). For these we
|
||||
" choose a sensible setting, which is using the current file's package
|
||||
let scopes = []
|
||||
if a:needs_scope
|
||||
let scopes = [pkg]
|
||||
endif
|
||||
|
||||
" check for any user defined scope setting. users can define the scope,
|
||||
" in package pattern form. examples:
|
||||
" golang.org/x/tools/cmd/guru # a single package
|
||||
" golang.org/x/tools/... # all packages beneath dir
|
||||
" ... # the entire workspace.
|
||||
if exists('g:go_guru_scope')
|
||||
" check that the setting is of type list
|
||||
if type(get(g:, 'go_guru_scope')) != type([])
|
||||
return {'err' : "go_guru_scope should of type list"}
|
||||
endif
|
||||
|
||||
let scopes = get(g:, 'go_guru_scope')
|
||||
endif
|
||||
|
||||
" now add the scope to our command if there is any
|
||||
if !empty(scopes)
|
||||
" strip trailing slashes for each path in scoped. bug:
|
||||
" https://github.com/golang/go/issues/14584
|
||||
let scopes = go#util#StripTrailingSlash(scopes)
|
||||
|
||||
" create shell-safe entries of the list
|
||||
let scopes = go#util#Shelllist(scopes)
|
||||
|
||||
" guru expect a comma-separated list of patterns, construct it
|
||||
let scope = join(scopes, ",")
|
||||
let command .= printf(" -scope %s", scope)
|
||||
endif
|
||||
|
||||
let pos = printf("#%s", go#util#OffsetCursor())
|
||||
if a:selected != -1
|
||||
" means we have a range, get it
|
||||
let pos1 = go#util#Offset(line("'<"), col("'<"))
|
||||
let pos2 = go#util#Offset(line("'>"), col("'>"))
|
||||
let pos = printf("#%s,#%s", pos1, pos2)
|
||||
endif
|
||||
|
||||
" this is our final command
|
||||
let command .= printf(' %s %s:%s', a:mode, shellescape(filename), pos)
|
||||
|
||||
let old_gopath = $GOPATH
|
||||
let $GOPATH = go#path#Detect()
|
||||
|
||||
" the query might take time, let us give some feedback
|
||||
call go#util#EchoProgress("analysing ...")
|
||||
|
||||
" run, forrest run!!!
|
||||
let out = go#util#System(command)
|
||||
|
||||
let $GOPATH = old_gopath
|
||||
if go#util#ShellError() != 0
|
||||
" the output contains the error message
|
||||
return {'err' : out}
|
||||
endif
|
||||
|
||||
return {'out': out}
|
||||
endfunc
|
||||
|
||||
" This uses Vim's errorformat to parse the output from Guru's 'plain output
|
||||
" and put it into location list. I believe using errorformat is much more
|
||||
" easier to use. If we need more power we can always switch back to parse it
|
||||
" via regex.
|
||||
func! s:loclistSecond(output)
|
||||
" backup users errorformat, will be restored once we are finished
|
||||
let old_errorformat = &errorformat
|
||||
|
||||
" match two possible styles of errorformats:
|
||||
"
|
||||
" 'file:line.col-line2.col2: message'
|
||||
" 'file:line:col: message'
|
||||
"
|
||||
" We discard line2 and col2 for the first errorformat, because it's not
|
||||
" useful and location only has the ability to show one line and column
|
||||
" number
|
||||
let errformat = "%f:%l.%c-%[%^:]%#:\ %m,%f:%l:%c:\ %m"
|
||||
call go#list#ParseFormat("locationlist", errformat, split(a:output, "\n"))
|
||||
|
||||
let errors = go#list#Get("locationlist")
|
||||
call go#list#Window("locationlist", len(errors))
|
||||
endfun
|
||||
|
||||
|
||||
function! go#guru#Scope(...)
|
||||
if a:0
|
||||
if a:0 == 1 && a:1 == '""'
|
||||
unlet g:go_guru_scope
|
||||
call go#util#EchoSuccess("guru scope is cleared")
|
||||
else
|
||||
let g:go_guru_scope = a:000
|
||||
call go#util#EchoSuccess("guru scope changed to: ". join(a:000, ","))
|
||||
endif
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
if !exists('g:go_guru_scope')
|
||||
call go#util#EchoError("guru scope is not set")
|
||||
else
|
||||
call go#util#EchoSuccess("current guru scope: ". join(g:go_guru_scope, ","))
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! go#guru#Tags(...)
|
||||
if a:0
|
||||
if a:0 == 1 && a:1 == '""'
|
||||
unlet g:go_guru_tags
|
||||
call go#util#EchoSuccess("guru tags is cleared")
|
||||
else
|
||||
let g:go_guru_tags = a:1
|
||||
call go#util#EchoSuccess("guru tags changed to: ". a:1)
|
||||
endif
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
if !exists('g:go_guru_tags')
|
||||
call go#util#EchoSuccess("guru tags is not set")
|
||||
else
|
||||
call go#util#EchoSuccess("current guru tags: ". a:1)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Show 'implements' relation for selected package
|
||||
function! go#guru#Implements(selected)
|
||||
let out = s:RunGuru('implements', 'plain', a:selected, 1)
|
||||
if has_key(out, 'err')
|
||||
call go#util#EchoError(out.err)
|
||||
return
|
||||
endif
|
||||
|
||||
call s:loclistSecond(out.out)
|
||||
endfunction
|
||||
|
||||
" Describe selected syntax: definition, methods, etc
|
||||
function! go#guru#Describe(selected)
|
||||
let out = s:RunGuru('describe', 'plain', a:selected, 0)
|
||||
if has_key(out, 'err')
|
||||
call go#util#EchoError(out.err)
|
||||
return
|
||||
endif
|
||||
|
||||
call s:loclistSecond(out.out)
|
||||
endfunction
|
||||
|
||||
" Show possible targets of selected function call
|
||||
function! go#guru#Callees(selected)
|
||||
let out = s:RunGuru('callees', 'plain', a:selected, 1)
|
||||
if has_key(out, 'err')
|
||||
call go#util#EchoError(out.err)
|
||||
return
|
||||
endif
|
||||
|
||||
call s:loclistSecond(out.out)
|
||||
endfunction
|
||||
|
||||
" Show possible callers of selected function
|
||||
function! go#guru#Callers(selected)
|
||||
let out = s:RunGuru('callers', 'plain', a:selected, 1)
|
||||
if has_key(out, 'err')
|
||||
call go#util#EchoError(out.err)
|
||||
return
|
||||
endif
|
||||
|
||||
call s:loclistSecond(out.out)
|
||||
endfunction
|
||||
|
||||
" Show path from callgraph root to selected function
|
||||
function! go#guru#Callstack(selected)
|
||||
let out = s:RunGuru('callstack', 'plain', a:selected, 1)
|
||||
if has_key(out, 'err')
|
||||
call go#util#EchoError(out.err)
|
||||
return
|
||||
endif
|
||||
|
||||
call s:loclistSecond(out.out)
|
||||
endfunction
|
||||
|
||||
" Show free variables of selection
|
||||
function! go#guru#Freevars(selected)
|
||||
" Freevars requires a selection
|
||||
if a:selected == -1
|
||||
call go#util#EchoError("GoFreevars requires a selection (range) of code")
|
||||
return
|
||||
endif
|
||||
|
||||
let out = s:RunGuru('freevars', 'plain', a:selected, 0)
|
||||
if has_key(out, 'err')
|
||||
call go#util#EchoError(out.err)
|
||||
return
|
||||
endif
|
||||
|
||||
call s:loclistSecond(out.out)
|
||||
endfunction
|
||||
|
||||
" Show send/receive corresponding to selected channel op
|
||||
function! go#guru#ChannelPeers(selected)
|
||||
let out = s:RunGuru('peers', 'plain', a:selected, 1)
|
||||
if has_key(out, 'err')
|
||||
call go#util#EchoError(out.err)
|
||||
return
|
||||
endif
|
||||
|
||||
call s:loclistSecond(out.out)
|
||||
endfunction
|
||||
|
||||
" Show all refs to entity denoted by selected identifier
|
||||
function! go#guru#Referrers(selected)
|
||||
let out = s:RunGuru('referrers', 'plain', a:selected, 0)
|
||||
if has_key(out, 'err')
|
||||
call go#util#EchoError(out.err)
|
||||
return
|
||||
endif
|
||||
|
||||
call s:loclistSecond(out.out)
|
||||
endfunction
|
||||
|
||||
function! go#guru#What(selected)
|
||||
" nvim doesn't have JSON support, though they work on it:
|
||||
" https://github.com/neovim/neovim/pull/4131
|
||||
if has('nvim')
|
||||
return {'err': "GoWhat is not supported in Neovim"}
|
||||
endif
|
||||
|
||||
" json_encode() and friends are introduced with this patch
|
||||
" https://groups.google.com/d/msg/vim_dev/vLupTNhQhZ8/cDGIk0JEDgAJ
|
||||
if !has('patch-7.4.1304')
|
||||
return {'err': "GoWhat is supported with Vim version 7.4-1304 or later"}
|
||||
endif
|
||||
|
||||
let out = s:RunGuru('what', 'json', a:selected, 0)
|
||||
if has_key(out, 'err')
|
||||
return out.err
|
||||
endif
|
||||
|
||||
call s:loclistSecond(out.out)
|
||||
let result = json_decode(out.out)
|
||||
|
||||
if type(result) != type({})
|
||||
return {'err': "malformed output from guru"}
|
||||
endif
|
||||
|
||||
if !has_key(result, 'what')
|
||||
return {'err': "no what query found for the given identifier"}
|
||||
endif
|
||||
|
||||
return {'out': result.what}
|
||||
endfunction
|
||||
|
||||
function! go#guru#SameIds(selected)
|
||||
let result = go#guru#What(a:selected)
|
||||
if has_key(out, 'err')
|
||||
call go#util#EchoError(out.err)
|
||||
return
|
||||
endif
|
||||
|
||||
if !has_key(result.out, 'sameids')
|
||||
call go#util#EchoError("no same_ids founds for the given identifier")
|
||||
return -1
|
||||
endif
|
||||
|
||||
let same_ids = result.what.sameids
|
||||
echo same_ids
|
||||
endfunction
|
||||
|
||||
" vim:ts=4:sw=4:et
|
124
sources_non_forked/vim-go/autoload/go/impl.vim
Normal file
124
sources_non_forked/vim-go/autoload/go/impl.vim
Normal file
@ -0,0 +1,124 @@
|
||||
function! go#impl#Impl(...)
|
||||
let binpath = go#path#CheckBinPath('impl')
|
||||
if empty(binpath)
|
||||
return
|
||||
endif
|
||||
|
||||
let recv = ""
|
||||
let iface = ""
|
||||
|
||||
if a:0 == 0
|
||||
" user didn't passed anything, just called ':GoImpl'
|
||||
let receiveType = expand("<cword>")
|
||||
let recv = printf("%s *%s", tolower(receiveType)[0], receiveType)
|
||||
let iface = input("vim-go: generating method stubs for interface: ")
|
||||
redraw!
|
||||
if empty(iface)
|
||||
call go#util#EchoError('usage: interface type is not provided')
|
||||
return
|
||||
endif
|
||||
elseif a:0 == 1
|
||||
" we assume the user only passed the interface type,
|
||||
" i.e: ':GoImpl io.Writer'
|
||||
let receiveType = expand("<cword>")
|
||||
let recv = printf("%s *%s", tolower(receiveType)[0], receiveType)
|
||||
let iface = a:1
|
||||
elseif a:0 > 2
|
||||
" user passed receiver and interface type both,
|
||||
" i.e: 'GoImpl f *Foo io.Writer'
|
||||
let recv = join(a:000[:-2], ' ')
|
||||
let iface = a:000[-1]
|
||||
else
|
||||
call go#util#EchoError('usage: GoImpl {receiver} {interface}')
|
||||
return
|
||||
endif
|
||||
|
||||
let result = go#util#System(printf("%s '%s' '%s'", binpath, recv, iface))
|
||||
if go#util#ShellError() != 0
|
||||
call go#util#EchoError(result)
|
||||
return
|
||||
endif
|
||||
|
||||
if result ==# ''
|
||||
return
|
||||
end
|
||||
|
||||
let pos = getpos('.')
|
||||
put =''
|
||||
put =result
|
||||
call setpos('.', pos)
|
||||
endfunction
|
||||
|
||||
if exists('*uniq')
|
||||
function! s:uniq(list)
|
||||
return uniq(a:list)
|
||||
endfunction
|
||||
else
|
||||
" Note: Believe that the list is sorted
|
||||
function! s:uniq(list)
|
||||
let i = len(a:list) - 1
|
||||
while 0 < i
|
||||
if a:list[i-1] ==# a:list[i]
|
||||
call remove(a:list, i)
|
||||
let i -= 2
|
||||
else
|
||||
let i -= 1
|
||||
endif
|
||||
endwhile
|
||||
return a:list
|
||||
endfunction
|
||||
endif
|
||||
|
||||
function! s:root_dirs()
|
||||
let dirs = []
|
||||
let root = go#util#GOROOT()
|
||||
if root !=# '' && isdirectory(root)
|
||||
call add(dirs, root)
|
||||
endif
|
||||
|
||||
let paths = map(split(go#util#GOPATH(), go#util#PathListSep()), "substitute(v:val, '\\\\', '/', 'g')")
|
||||
if go#util#ShellError()
|
||||
return []
|
||||
endif
|
||||
|
||||
if !empty(filter(paths, 'isdirectory(v:val)'))
|
||||
call extend(dirs, paths)
|
||||
endif
|
||||
|
||||
return dirs
|
||||
endfunction
|
||||
|
||||
function! s:go_packages(dirs)
|
||||
let pkgs = []
|
||||
for d in a:dirs
|
||||
let pkg_root = expand(d . '/pkg/' . go#util#OSARCH())
|
||||
call extend(pkgs, split(globpath(pkg_root, '**/*.a', 1), "\n"))
|
||||
endfor
|
||||
return map(pkgs, "fnamemodify(v:val, ':t:r')")
|
||||
endfunction
|
||||
|
||||
function! s:interface_list(pkg)
|
||||
let contents = split(go#util#System('go doc ' . a:pkg), "\n")
|
||||
if go#util#ShellError()
|
||||
return []
|
||||
endif
|
||||
|
||||
call filter(contents, 'v:val =~# ''^type\s\+\h\w*\s\+interface''')
|
||||
return map(contents, 'a:pkg . "." . matchstr(v:val, ''^type\s\+\zs\h\w*\ze\s\+interface'')')
|
||||
endfunction
|
||||
|
||||
" Complete package and interface for {interface}
|
||||
function! go#impl#Complete(arglead, cmdline, cursorpos)
|
||||
let words = split(a:cmdline, '\s\+', 1)
|
||||
if words[-1] ==# ''
|
||||
return s:uniq(sort(s:go_packages(s:root_dirs())))
|
||||
elseif words[-1] =~# '^\h\w*$'
|
||||
return s:uniq(sort(filter(s:go_packages(s:root_dirs()), 'stridx(v:val, words[-1]) == 0')))
|
||||
elseif words[-1] =~# '^\h\w*\.\%(\h\w*\)\=$'
|
||||
let [pkg, interface] = split(words[-1], '\.', 1)
|
||||
echomsg pkg
|
||||
return s:uniq(sort(filter(s:interface_list(pkg), 'v:val =~? words[-1]')))
|
||||
else
|
||||
return []
|
||||
endif
|
||||
endfunction
|
@ -27,8 +27,8 @@ function! go#import#SwitchImport(enabled, localname, path, bang)
|
||||
endif
|
||||
|
||||
if a:bang == "!"
|
||||
let out = system("go get -u -v ".shellescape(path))
|
||||
if v:shell_error
|
||||
let out = go#util#System("go get -u -v ".shellescape(path))
|
||||
if go#util#ShellError() != 0
|
||||
call s:Error("Can't find import: " . path . ":" . out)
|
||||
endif
|
||||
endif
|
||||
|
@ -64,7 +64,7 @@ function! go#lint#Gometa(autosave, ...) abort
|
||||
let out = go#tool#ExecuteInDir(meta_command)
|
||||
|
||||
let l:listtype = "quickfix"
|
||||
if v:shell_error == 0
|
||||
if go#util#ShellError() == 0
|
||||
redraw | echo
|
||||
call go#list#Clean(l:listtype)
|
||||
call go#list#Window(l:listtype)
|
||||
@ -102,7 +102,7 @@ function! go#lint#Golint(...) abort
|
||||
let goargs = go#util#Shelljoin(a:000)
|
||||
endif
|
||||
|
||||
let out = system(bin_path . " " . goargs)
|
||||
let out = go#util#System(bin_path . " " . goargs)
|
||||
if empty(out)
|
||||
echon "vim-go: " | echohl Function | echon "[lint] PASS" | echohl None
|
||||
return
|
||||
@ -127,7 +127,7 @@ function! go#lint#Vet(bang, ...)
|
||||
endif
|
||||
|
||||
let l:listtype = "quickfix"
|
||||
if v:shell_error
|
||||
if go#util#ShellError() != 0
|
||||
let errors = go#tool#ParseErrors(split(out, '\n'))
|
||||
call go#list#Populate(l:listtype, errors)
|
||||
call go#list#Window(l:listtype, len(errors))
|
||||
@ -167,7 +167,7 @@ function! go#lint#Errcheck(...) abort
|
||||
let out = go#tool#ExecuteInDir(command)
|
||||
|
||||
let l:listtype = "quickfix"
|
||||
if v:shell_error
|
||||
if go#util#ShellError() != 0
|
||||
let errformat = "%f:%l:%c:\ %m, %f:%l:%c\ %#%m"
|
||||
|
||||
" Parse and populate our location list
|
||||
|
@ -1,233 +0,0 @@
|
||||
" oracle.vim -- Vim integration for the Go oracle.
|
||||
"
|
||||
" Part of this plugin was taken directly from the oracle repo, however it's
|
||||
" massively changed for a better integration into vim-go. Thanks Alan Donovan
|
||||
" for the first iteration based on quickfix! - Fatih Arslan
|
||||
"
|
||||
|
||||
if !exists("g:go_oracle_bin")
|
||||
let g:go_oracle_bin = "oracle"
|
||||
endif
|
||||
|
||||
" Parses (via regex) Oracle's 'plain' format output and puts them into a
|
||||
" location list
|
||||
func! s:loclist(output)
|
||||
let llist = []
|
||||
" Parse GNU-style 'file:line.col-line.col: message' format.
|
||||
let mx = '^\(\a:[\\/][^:]\+\|[^:]\+\):\(\d\+\):\(\d\+\):\(.*\)$'
|
||||
for line in split(a:output, "\n")
|
||||
let ml = matchlist(line, mx)
|
||||
|
||||
" Ignore non-match lines or warnings
|
||||
if ml == [] || ml[4] =~ '^ warning:'
|
||||
continue
|
||||
endif
|
||||
|
||||
let item = {
|
||||
\ 'filename': ml[1],
|
||||
\ 'text': ml[4],
|
||||
\ 'lnum': ml[2],
|
||||
\ 'col': ml[3],
|
||||
\}
|
||||
let bnr = bufnr(fnameescape(ml[1]))
|
||||
if bnr != -1
|
||||
let item['bufnr'] = bnr
|
||||
endif
|
||||
call add(llist, item)
|
||||
endfor
|
||||
call go#list#Populate("locationlist", llist)
|
||||
call go#list#Window("locationlist", len(llist))
|
||||
endfun
|
||||
|
||||
" This uses Vim's errorformat to parse the output from Oracle's 'plain output
|
||||
" and put it into location list. I believe using errorformat is much more
|
||||
" easier to use. If we need more power we can always switch back to parse it
|
||||
" via regex.
|
||||
func! s:loclistSecond(output)
|
||||
" backup users errorformat, will be restored once we are finished
|
||||
let old_errorformat = &errorformat
|
||||
|
||||
" match two possible styles of errorformats:
|
||||
"
|
||||
" 'file:line.col-line2.col2: message'
|
||||
" 'file:line:col: message'
|
||||
"
|
||||
" We discard line2 and col2 for the first errorformat, because it's not
|
||||
" useful and location only has the ability to show one line and column
|
||||
" number
|
||||
let errformat = "%f:%l.%c-%[%^:]%#:\ %m,%f:%l:%c:\ %m"
|
||||
call go#list#ParseFormat("locationlist", errformat, split(a:output, "\n"))
|
||||
|
||||
let errors = go#list#Get("locationlist")
|
||||
call go#list#Window("locationlist", len(errors))
|
||||
endfun
|
||||
|
||||
func! s:RunOracle(mode, selected, needs_package) range abort
|
||||
let fname = expand('%:p')
|
||||
let dname = expand('%:p:h')
|
||||
let pkg = go#package#ImportPath(dname)
|
||||
|
||||
if exists('g:go_oracle_scope')
|
||||
" let the user defines the scope, must be a space separated string,
|
||||
" example: 'fmt math net/http'
|
||||
let scopes = split(get(g:, 'go_oracle_scope'))
|
||||
elseif a:needs_package || exists('g:go_oracle_include_tests') && pkg != -1
|
||||
" give import path so it includes all _test.go files too
|
||||
let scopes = [pkg]
|
||||
else
|
||||
" best usable way, only pass the package itself, without the test
|
||||
" files
|
||||
let scopes = go#tool#Files()
|
||||
endif
|
||||
|
||||
"return with a warning if the bin doesn't exist
|
||||
let bin_path = go#path#CheckBinPath(g:go_oracle_bin)
|
||||
if empty(bin_path)
|
||||
return
|
||||
endif
|
||||
|
||||
if exists('g:go_oracle_tags')
|
||||
let tags = get(g:, 'go_oracle_tags')
|
||||
else
|
||||
let tags = ""
|
||||
endif
|
||||
|
||||
if a:selected != -1
|
||||
let pos1 = go#util#Offset(line("'<"), col("'<"))
|
||||
let pos2 = go#util#Offset(line("'>"), col("'>"))
|
||||
let cmd = printf('%s -format plain -pos=%s:#%d,#%d -tags=%s %s',
|
||||
\ bin_path,
|
||||
\ shellescape(fname), pos1, pos2, tags, a:mode)
|
||||
else
|
||||
let pos = go#util#OffsetCursor()
|
||||
let cmd = printf('%s -format plain -pos=%s:#%d -tags=%s %s',
|
||||
\ bin_path,
|
||||
\ shellescape(fname), pos, tags, a:mode)
|
||||
endif
|
||||
|
||||
" strip trailing slashes for each path in scoped. bug:
|
||||
" https://github.com/golang/go/issues/14584
|
||||
let scopes = go#util#StripTrailingSlash(scopes)
|
||||
|
||||
" now append each scope to the end as Oracle's scope parameter. It can be
|
||||
" a packages or go files, dependent on the User's own choice. For more
|
||||
" info check Oracle's User Manual section about scopes:
|
||||
" https://docs.google.com/document/d/1SLk36YRjjMgKqe490mSRzOPYEDe0Y_WQNRv-EiFYUyw/view#heading=h.nwso96pj07q8
|
||||
let cmd .= ' ' . go#util#Shelljoin(scopes)
|
||||
|
||||
echon "vim-go: " | echohl Identifier | echon "analysing ..." | echohl None
|
||||
|
||||
let old_gopath = $GOPATH
|
||||
let $GOPATH = go#path#Detect()
|
||||
|
||||
let out = system(cmd)
|
||||
|
||||
let $GOPATH = old_gopath
|
||||
|
||||
if v:shell_error
|
||||
" unfortunaly oracle outputs a very long stack trace that is not
|
||||
" parsable to show the real error. But the main issue is usually the
|
||||
" package which doesn't build.
|
||||
redraw | echon "vim-go: " | echohl Statement | echon out | echohl None
|
||||
return ""
|
||||
endif
|
||||
|
||||
return out
|
||||
endfunc
|
||||
|
||||
function! go#oracle#Scope(...)
|
||||
if a:0
|
||||
if a:0 == 1 && a:1 == '""'
|
||||
unlet g:go_oracle_scope
|
||||
echon "vim-go: " | echohl Function | echon "oracle scope is cleared"| echohl None
|
||||
else
|
||||
let g:go_oracle_scope = join(a:000, ' ')
|
||||
echon "vim-go: " | echohl Function | echon "oracle scope changed to: '". g:go_oracle_scope ."'" | echohl None
|
||||
endif
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
if !exists('g:go_oracle_scope')
|
||||
echon "vim-go: " | echohl Function | echon "oracle scope is not set"| echohl None
|
||||
else
|
||||
echon "vim-go: " | echohl Function | echon "current oracle scope: '". g:go_oracle_scope ."'" | echohl None
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! go#oracle#Tags(...)
|
||||
if a:0
|
||||
if a:0 == 1 && a:1 == '""'
|
||||
unlet g:go_oracle_tags
|
||||
echon "vim-go: " | echohl Function | echon "oracle tags is cleared"| echohl None
|
||||
else
|
||||
let g:go_oracle_tags = a:1
|
||||
echon "vim-go: " | echohl Function | echon "oracle tags changed to: '". g:go_oracle_tags ."'" | echohl None
|
||||
endif
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
if !exists('g:go_oracle_tags')
|
||||
echon "vim-go: " | echohl Function | echon "oracle tags is not set"| echohl None
|
||||
else
|
||||
echon "vim-go: " | echohl Function | echon "current oracle tags: '". g:go_oracle_tags ."'" | echohl None
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Show 'implements' relation for selected package
|
||||
function! go#oracle#Implements(selected)
|
||||
let out = s:RunOracle('implements', a:selected, 0)
|
||||
call s:loclistSecond(out)
|
||||
endfunction
|
||||
|
||||
" Describe selected syntax: definition, methods, etc
|
||||
function! go#oracle#Describe(selected)
|
||||
let out = s:RunOracle('describe', a:selected, 0)
|
||||
call s:loclistSecond(out)
|
||||
endfunction
|
||||
|
||||
" Show possible targets of selected function call
|
||||
function! go#oracle#Callees(selected)
|
||||
let out = s:RunOracle('callees', a:selected, 1)
|
||||
call s:loclistSecond(out)
|
||||
endfunction
|
||||
|
||||
" Show possible callers of selected function
|
||||
function! go#oracle#Callers(selected)
|
||||
let out = s:RunOracle('callers', a:selected, 1)
|
||||
call s:loclistSecond(out)
|
||||
endfunction
|
||||
|
||||
" Show path from callgraph root to selected function
|
||||
function! go#oracle#Callstack(selected)
|
||||
let out = s:RunOracle('callstack', a:selected, 1)
|
||||
call s:loclistSecond(out)
|
||||
endfunction
|
||||
|
||||
" Show free variables of selection
|
||||
function! go#oracle#Freevars(selected)
|
||||
" Freevars requires a selection
|
||||
if a:selected == -1
|
||||
echon "vim-go: " | echohl Statement | echon "GoFreevars requires a selection (range) of code "| echohl None
|
||||
return
|
||||
endif
|
||||
|
||||
let out = s:RunOracle('freevars', a:selected, 0)
|
||||
call s:loclistSecond(out)
|
||||
endfunction
|
||||
|
||||
" Show send/receive corresponding to selected channel op
|
||||
function! go#oracle#ChannelPeers(selected)
|
||||
let out = s:RunOracle('peers', a:selected, 1)
|
||||
call s:loclistSecond(out)
|
||||
endfunction
|
||||
|
||||
" Show all refs to entity denoted by selected identifier
|
||||
function! go#oracle#Referrers(selected)
|
||||
let out = s:RunOracle('referrers', a:selected, 0)
|
||||
call s:loclistSecond(out)
|
||||
endfunction
|
||||
|
||||
" vim:ts=4:sw=4:et
|
||||
"
|
@ -33,8 +33,8 @@ function! go#package#Paths()
|
||||
|
||||
if !exists("s:goroot")
|
||||
if executable('go')
|
||||
let s:goroot = substitute(system('go env GOROOT'), '\n', '', 'g')
|
||||
if v:shell_error
|
||||
let s:goroot = substitute(go#util#System('go env GOROOT'), '\n', '', 'g')
|
||||
if go#util#ShellError() != 0
|
||||
echomsg '''go env GOROOT'' failed'
|
||||
endif
|
||||
else
|
||||
@ -95,8 +95,8 @@ function! go#package#FromPath(arg)
|
||||
endfunction
|
||||
|
||||
function! go#package#CompleteMembers(package, member)
|
||||
silent! let content = system('godoc ' . a:package)
|
||||
if v:shell_error || !len(content)
|
||||
silent! let content = go#util#System('godoc ' . a:package)
|
||||
if go#util#ShellError() || !len(content)
|
||||
return []
|
||||
endif
|
||||
let lines = filter(split(content, "\n"),"v:val !~ '^\\s\\+$'")
|
||||
@ -117,7 +117,7 @@ function! go#package#Complete(ArgLead, CmdLine, CursorPos)
|
||||
let words = split(a:CmdLine, '\s\+', 1)
|
||||
|
||||
" do not complete package members for these commands
|
||||
let neglect_commands = ["GoImportAs", "GoOracleScope"]
|
||||
let neglect_commands = ["GoImportAs", "GoGuruScope"]
|
||||
|
||||
if len(words) > 2 && index(neglect_commands, words[0]) == -1
|
||||
" Complete package members
|
||||
|
@ -138,27 +138,25 @@ endfunction
|
||||
function! go#path#CheckBinPath(binpath)
|
||||
" remove whitespaces if user applied something like 'goimports '
|
||||
let binpath = substitute(a:binpath, '^\s*\(.\{-}\)\s*$', '\1', '')
|
||||
" save off original path
|
||||
let old_path = $PATH
|
||||
|
||||
" check if we have an appropriate bin_path
|
||||
let go_bin_path = go#path#BinPath()
|
||||
if !empty(go_bin_path)
|
||||
" append our GOBIN and GOPATH paths and be sure they can be found there...
|
||||
" let us search in our GOBIN and GOPATH paths
|
||||
let $PATH = go_bin_path . go#util#PathListSep() . $PATH
|
||||
endif
|
||||
|
||||
" if it's in PATH just return it
|
||||
if executable(binpath)
|
||||
if executable(binpath)
|
||||
let $PATH = old_path
|
||||
return binpath
|
||||
endif
|
||||
|
||||
" just get the basename
|
||||
let basename = fnamemodify(binpath, ":t")
|
||||
|
||||
" check if we have an appropriate bin_path
|
||||
let go_bin_path = go#path#BinPath()
|
||||
if empty(go_bin_path)
|
||||
echo "vim-go: could not find '" . basename . "'. Run :GoInstallBinaries to fix it."
|
||||
return ""
|
||||
endif
|
||||
|
||||
" append our GOBIN and GOPATH paths and be sure they can be found there...
|
||||
" let us search in our GOBIN and GOPATH paths
|
||||
let old_path = $PATH
|
||||
let $PATH = $PATH . go#util#PathListSep() .go_bin_path
|
||||
|
||||
if !executable(basename)
|
||||
echo "vim-go: could not find '" . basename . "'. Run :GoInstallBinaries to fix it."
|
||||
" restore back!
|
||||
|
@ -13,13 +13,13 @@ function! go#play#Share(count, line1, line2)
|
||||
let share_file = tempname()
|
||||
call writefile(split(content, "\n"), share_file, "b")
|
||||
|
||||
let command = "curl -s -X POST http://play.golang.org/share --data-binary '@".share_file."'"
|
||||
let snippet_id = system(command)
|
||||
let command = "curl -s -X POST https://play.golang.org/share --data-binary '@".share_file."'"
|
||||
let snippet_id = go#util#System(command)
|
||||
|
||||
" we can remove the temp file because it's now posted.
|
||||
call delete(share_file)
|
||||
|
||||
if v:shell_error
|
||||
if go#util#ShellError() != 0
|
||||
echo 'A error has occured. Run this command to see what the problem is:'
|
||||
echo command
|
||||
return
|
||||
@ -77,7 +77,7 @@ function! s:get_browser_command()
|
||||
if go_play_browser_command == ''
|
||||
if has('win32') || has('win64')
|
||||
let go_play_browser_command = '!start rundll32 url.dll,FileProtocolHandler %URL%'
|
||||
elseif has('mac') || has('macunix') || has('gui_macvim') || system('uname') =~? '^darwin'
|
||||
elseif has('mac') || has('macunix') || has('gui_macvim') || go#util#System('uname') =~? '^darwin'
|
||||
let go_play_browser_command = 'open %URL%'
|
||||
elseif executable('xdg-open')
|
||||
let go_play_browser_command = 'xdg-open %URL%'
|
||||
|
@ -41,7 +41,7 @@ function! go#rename#Rename(bang, ...)
|
||||
let clean = split(out, '\n')
|
||||
|
||||
let l:listtype = "quickfix"
|
||||
if v:shell_error
|
||||
if go#util#ShellError() != 0
|
||||
let errors = go#tool#ParseErrors(split(out, '\n'))
|
||||
call go#list#Populate(l:listtype, errors)
|
||||
call go#list#Window(l:listtype, len(errors))
|
||||
|
@ -36,8 +36,8 @@ function! go#textobj#Function(mode)
|
||||
let command .= " -parse-comments"
|
||||
endif
|
||||
|
||||
let out = system(command)
|
||||
if v:shell_error != 0
|
||||
let out = go#util#System(command)
|
||||
if go#util#ShellError() != 0
|
||||
call go#util#EchoError(out)
|
||||
return
|
||||
endif
|
||||
@ -129,8 +129,8 @@ function! go#textobj#FunctionJump(mode, direction)
|
||||
let command .= " -parse-comments"
|
||||
endif
|
||||
|
||||
let out = system(command)
|
||||
if v:shell_error != 0
|
||||
let out = go#util#System(command)
|
||||
if go#util#ShellError() != 0
|
||||
call go#util#EchoError(out)
|
||||
return
|
||||
endif
|
||||
|
@ -26,7 +26,7 @@ function! go#tool#Imports()
|
||||
let command = "go list -f $'{{range $f := .Imports}}{{$f}}\n{{end}}'"
|
||||
endif
|
||||
let out = go#tool#ExecuteInDir(command)
|
||||
if v:shell_error
|
||||
if go#util#ShellError() != 0
|
||||
echo out
|
||||
return imports
|
||||
endif
|
||||
@ -51,7 +51,7 @@ function! go#tool#ParseErrors(lines)
|
||||
call add(errors, {"text": fatalerrors[1]})
|
||||
elseif !empty(tokens)
|
||||
" strip endlines of form ^M
|
||||
let out=substitute(tokens[3], '\r$', '', '')
|
||||
let out = substitute(tokens[3], '\r$', '', '')
|
||||
|
||||
call add(errors, {
|
||||
\ "filename" : fnamemodify(tokens[1], ':p'),
|
||||
@ -114,7 +114,7 @@ function! go#tool#ExecuteInDir(cmd) abort
|
||||
let dir = getcwd()
|
||||
try
|
||||
execute cd . fnameescape(expand("%:p:h"))
|
||||
let out = system(a:cmd)
|
||||
let out = go#util#System(a:cmd)
|
||||
finally
|
||||
execute cd . fnameescape(dir)
|
||||
endtry
|
||||
@ -129,7 +129,7 @@ function! go#tool#Exists(importpath)
|
||||
let command = "go list ". a:importpath
|
||||
let out = go#tool#ExecuteInDir(command)
|
||||
|
||||
if v:shell_error
|
||||
if go#util#ShellError() != 0
|
||||
return -1
|
||||
endif
|
||||
|
||||
@ -144,7 +144,7 @@ function! s:get_browser_command()
|
||||
if go_play_browser_command == ''
|
||||
if go#util#IsWin()
|
||||
let go_play_browser_command = '!start rundll32 url.dll,FileProtocolHandler %URL%'
|
||||
elseif has('mac') || has('macunix') || has('gui_macvim') || system('uname') =~? '^darwin'
|
||||
elseif has('mac') || has('macunix') || has('gui_macvim') || go#util#System('uname') =~? '^darwin'
|
||||
let go_play_browser_command = 'open %URL%'
|
||||
elseif executable('xdg-open')
|
||||
let go_play_browser_command = 'xdg-open %URL%'
|
||||
@ -175,7 +175,7 @@ function! go#tool#OpenBrowser(url)
|
||||
exec cmd
|
||||
else
|
||||
let cmd = substitute(cmd, '%URL%', '\=shellescape(a:url)', 'g')
|
||||
call system(cmd)
|
||||
call go#util#System(cmd)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
@ -37,6 +37,67 @@ function! go#util#IsWin()
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
function! go#util#GOARCH()
|
||||
return substitute(go#util#System('go env GOARCH'), '\n', '', 'g')
|
||||
endfunction
|
||||
|
||||
function! go#util#GOOS()
|
||||
return substitute(go#util#System('go env GOOS'), '\n', '', 'g')
|
||||
endfunction
|
||||
|
||||
function! go#util#GOROOT()
|
||||
return substitute(go#util#System('go env GOROOT'), '\n', '', 'g')
|
||||
endfunction
|
||||
|
||||
function! go#util#GOPATH()
|
||||
return substitute(go#util#System('go env GOPATH'), '\n', '', 'g')
|
||||
endfunction
|
||||
|
||||
function! go#util#OSARCH()
|
||||
return go#util#GOOS() . '_' . go#util#GOARCH()
|
||||
endfunction
|
||||
|
||||
|
||||
"Check if has vimproc
|
||||
function! s:has_vimproc()
|
||||
if !exists('g:go#use_vimproc')
|
||||
if go#util#IsWin()
|
||||
try
|
||||
call vimproc#version()
|
||||
let exists_vimproc = 1
|
||||
catch
|
||||
let exists_vimproc = 0
|
||||
endtry
|
||||
else
|
||||
let exists_vimproc = 0
|
||||
endif
|
||||
|
||||
let g:go#use_vimproc = exists_vimproc
|
||||
endif
|
||||
|
||||
return g:go#use_vimproc
|
||||
endfunction
|
||||
|
||||
if s:has_vimproc()
|
||||
let s:vim_system = get(g:, 'gocomplete#system_function', 'vimproc#system2')
|
||||
let s:vim_shell_error = get(g:, 'gocomplete#shell_error_function', 'vimproc#get_last_status')
|
||||
else
|
||||
let s:vim_system = get(g:, 'gocomplete#system_function', 'system')
|
||||
let s:vim_shell_error = ''
|
||||
endif
|
||||
|
||||
function! go#util#System(str, ...)
|
||||
return call(s:vim_system, [a:str] + a:000)
|
||||
endfunction
|
||||
|
||||
function! go#util#ShellError()
|
||||
if empty(s:vim_shell_error)
|
||||
return v:shell_error
|
||||
endif
|
||||
return call(s:vim_shell_error, [])
|
||||
endfunction
|
||||
|
||||
|
||||
" StripPath strips the path's last character if it's a path separator.
|
||||
" example: '/foo/bar/' -> '/foo/bar'
|
||||
function! go#util#StripPathSep(path)
|
||||
@ -70,6 +131,19 @@ function! go#util#Shelljoin(arglist, ...)
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
fu! go#util#Shellescape(arg)
|
||||
if s:has_vimproc()
|
||||
return vimproc#shellescape(a:arg)
|
||||
endif
|
||||
try
|
||||
let ssl_save = &shellslash
|
||||
set noshellslash
|
||||
return shellescape(a:arg)
|
||||
finally
|
||||
let &shellslash = ssl_save
|
||||
endtry
|
||||
endf
|
||||
|
||||
" Shelllist returns a shell-safe representation of the items in the given
|
||||
" arglist. The {special} argument of shellescape() may optionally be passed.
|
||||
function! go#util#Shelllist(arglist, ...)
|
||||
|
@ -1,21 +0,0 @@
|
||||
"Check if has vimproc
|
||||
function! go#vimproc#has_vimproc()
|
||||
if !exists('g:go#use_vimproc')
|
||||
if go#util#IsWin()
|
||||
try
|
||||
call vimproc#version()
|
||||
let exists_vimproc = 1
|
||||
catch
|
||||
let exists_vimproc = 0
|
||||
endtry
|
||||
else
|
||||
let exists_vimproc = 0
|
||||
endif
|
||||
|
||||
let g:go#use_vimproc = exists_vimproc
|
||||
endif
|
||||
|
||||
return g:go#use_vimproc
|
||||
endfunction
|
||||
|
||||
" vim:ts=4:sw=4:et
|
Reference in New Issue
Block a user