1
0
mirror of https://github.com/amix/vimrc synced 2025-06-16 09:35:01 +08:00

Updated plugins

This commit is contained in:
amix
2016-05-14 12:57:54 +01:00
parent 5f6aa8fe09
commit f343b66088
105 changed files with 2100 additions and 4902 deletions

View File

@ -1,27 +1,94 @@
## 1.6 (unreleased)
## 1.7 (unreleased)
FEATURES:
* New **`:GoImpl`** command that generates method stubs for implementing an interface. Checkout the [demo](https://twitter.com/fatih/status/729991365581545472) to see how it works. [gh-846]
* New `<C-w><C-]>` and `<C-w>]>` shortcuts to split current window and jumpt to the identifier under cursor. [gh-838]
IMPROVEMENTS:
* Enable passing the `-tags` flag to `:GoDef`. Now you can pass build tags to `:GoDef` via `:GoGuruTags` or `g:go_guru_tags`
* Internal refactoring to use custom `system()` function that wraps both the standard `system()` call and `vimproc`. Now all system calls will take advantage and will use `vimproc` if installed. [gh-801]
* Added new `http.HandlerFunc` snippets with `hf` and `hhf` shortcuts [gh-816]
* Added new `Example` and `Benchmark` snippets with `example` and `benchmark` shortcuts [gh-836]
* Search tool binaries first in `GOBIN` and then in `PATH` as most of vim-go users installs it to `GOBIN` mostly [gh-823]
BUG FIXES:
* Fix `(go-freevars)` plug mapping to work as in visual mode instead of noncompatible normal mode [gh-832]
* Commands based on guru now shows a more meaningful error message instead of just showing the exit status (-1)
* Fix `:GoCoverage` accidently enabling syntax highlighting for users who don't use syntax (i.e syntax off) [gh-827]
* Fix commenting out block of texts for Go templates (filetype gothtmltmpl) [gh-813]
* Fix `:GoImplements` failing because of an empty scope definition. Now we default to current package to make it usable.
* Fix `:GoPlay` posting to non HTTPS url. [gh-847]
## 1.6 (April 25, 2016)
FEATURES:
* New `CHANGELOG.md` file (which you're reading now). This will make it easier
for me to track changes and release versions
* **`:GoCoverage`**: is now highlighting the current source file for
covered/uncovered lines. If called again it clears the highlighting. This is
a pretty good addition to vim-go and I suggest to check out the gif that shows
it in action: https://twitter.com/fatih/status/716722650383564800 [gh-786]
* **`:GoCoverageBrowser`**: opens a new annotated HTML page. This is the old
* **`:GoCoverage`** is now highlighting the current source file for
covered/uncovered lines. If called again it runs the tests and updates the
annotation. Use `:GoCoverageClear` to clear the coverage annotation.
This is a pretty good addition to vim-go and I suggest to check out the gif
that shows it in action: https://twitter.com/fatih/status/716722650383564800
[gh-786]
* **`:GoCoverageToggle`** just like `:GoCoverage` but acts as a toggle. If run
again it clears the annotation.
* **`:GoCoverageBrowser`** opens a new annotated HTML page. This is the old
`:GoCoverage` behavior [gh-786]
* **`GoDoc`**: uses now `[gogetdoc](https://github.com/zmb3/gogetdoc)` to
* **`:GoDoc`** uses now [gogetdoc](https://github.com/zmb3/gogetdoc) to
lookup and display the comment documentation for the identifier under the
cursor. This is more superior as it support looking up dot imports, named
imports and imports where package name and file name are different [gh-782]
* **`guru support`**: `oracle` is replaced by the new tool `guru`. `oracle.vim`
is therefore renamed to `guru.vim`. I've also refactored the code to make it
much more easier to maintain and add additional features in future (such as
upcoming JSON decoding). vim-go is now fully compatible with `guru`. Please
be sure you have installed `guru`. You can easily do it with
`:GoInstallBinaries`.
* **`:GoDef`** uses now `guru definition` under the hood instead of `godef`.
This fixes the following issues: 1. dot imports 2. vendor imports 3. folder
!= package name imports. The tool `godef` is also deprecated and not used
anymore.
* **`:GoDef`** does have now history of the call stack. This means you can
easily jump back to your last entry. This can be done with the new command
`:GoDefPop` or the mapping `CTRL-t`. To see the stack and jump between entries
you can use the new command `:GoDefStack`, which shows the list of all stack
entries. To reset the stack list anytime you can call `:GoDefStackClear`
[gh-776]
IMPROVEMENTS:
* **`:GoCoverage`** is now executed async when used within Neovim [gh-686]
* **`:GoCoverage`** is executed asynchronously when used within Neovim [gh-686]
* **`:GoTestFunc`** supports now testable examples [gh-794]
* **`:GoDef`** can jump to existing buffers instead of opening a new window
(split, vsplit or tab). By default it's disabled to not break the old
behavior, can be enabled with `let g:go_def_reuse_buffer = 1`
BUG FIXES:
* Fix not showing documentation for dot, named and package/file name being different imports [gh-332]
* Term mode: fix closing location list if result is successful after a failed attempt [gh-768]
* Syntax: fix gotexttmpl identifier highlighting [gh-778]
* Doc: fix wrong wording for `go-run` mapping. It's for the whole main package,
not for the current file
BACKWARDS INCOMPATIBILITIES:
* `:GoDef` doesn't accept any identifier as an argument. This is not suported
via `guru definition` and also was not widely used either. Also with this, we
significantly simplified the existing def.vim code
* `:GoOracleScope` and `:GoOracleTags` are deprecated in favor of
`:GoGuruScope` and `:GoGuruTags`. Also `g:go_oracle_scope` is renamed to
`g:go_guru_scope`
* `g:go_guru_scope` accepts a variable in type of `list` instead of `string`.
i.g: `let g:go_guru_scope = ["github.com/fatih/structs", "golang.org/x/tools/..."]`
## Previous releases
Previous changelogs can be found here: https://github.com/fatih/vim-go/releases

View File

@ -30,7 +30,7 @@ disabled/enabled easily.
(golint, vet, errcheck, deadcode, etc..) and shows the warnings/errors
* Lint your code with `:GoLint`
* Run your code through `:GoVet` to catch static errors
* Advanced source analysis tools utilizing oracle, such as `:GoImplements`,
* Advanced source analysis tools utilizing guru, such as `:GoImplements`,
`:GoCallees`, and `:GoReferrers`
* Precise type-safe renaming of identifiers with `:GoRename`
* List all source files and dependencies
@ -50,14 +50,11 @@ disabled/enabled easily.
in their own new terminal. (beta)
* Alternate between implementation and test code with `:GoAlternate`
## Donation
People have asked for this for a long time, now you can be a fully supporter by [being a patron](https://www.patreon.com/fatih)! This is fully optional and is just a way to support vim-go's ongoing development directly. Thanks!
[https://www.patreon.com/fatih](https://www.patreon.com/fatih)
## Install
Master branch is supposed to be a development branch. So stuff here can break and change.
Please try use always the [latest release](https://github.com/fatih/vim-go/releases/latest)
Vim-go follows the standard runtime path structure, so I highly recommend to
use a common and well known plugin manager to install vim-go. Do not use vim-go
with other Go oriented vim plugins. For Pathogen just clone the repo. For other
@ -108,10 +105,11 @@ After that just open the help page to see all commands:
:help vim-go
## Mappings
## Example Mappings
vim-go has several `<Plug>` mappings which can be used to create custom
mappings. Below are some examples you might find useful:
mappings. Unless otherwise specified, none of these mappings are enabled
by default. Here some examples you might find useful:
Run commands such as `go run` for the current file with `<leader>r` or `go
build` and `go test` for the current package with `<leader>b` and `<leader>t`
@ -259,6 +257,15 @@ let g:syntastic_go_checkers = ['golint', 'govet', 'errcheck']
let g:syntastic_mode_map = { 'mode': 'active', 'passive_filetypes': ['go'] }
```
Another issue with `vim-go` and `syntastic` is that the location list window
that contains the output of commands such as `:GoBuild` and `:GoTest` might not appear.
To resolve this:
```vim
let g:go_list_type = "quickfix"
```
## More info
Check out the [Wiki](https://github.com/fatih/vim-go/wiki) page for more
@ -267,10 +274,18 @@ information. It includes
section](https://github.com/fatih/vim-go/wiki/FAQ-Troubleshooting), and many
other [various pieces](https://github.com/fatih/vim-go/wiki) of information.
## Donation
People have asked for this for a long time, now you can be a fully supporter by
[being a patron](https://www.patreon.com/fatih)! This is fully optional and is
just a way to support vim-go's ongoing development directly. Thanks!
[https://www.patreon.com/fatih](https://www.patreon.com/fatih)
## Credits
* Go Authors for official vim plugins
* Gocode, Godef, Golint, Oracle, Goimports, Gotags, Errcheck projects and
* Gocode, Godef, Golint, Guru, Goimports, Gotags, Errcheck projects and
authors of those projects.
* Other vim-plugins, thanks for inspiration (vim-golang, go.vim, vim-gocode,
vim-godef)

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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'

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View 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

View 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

View File

@ -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

View File

@ -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

View File

@ -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
"

View File

@ -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

View File

@ -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!

View File

@ -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%'

View File

@ -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))

View File

@ -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

View File

@ -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

View File

@ -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, ...)

View File

@ -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

View File

@ -53,7 +53,7 @@ easily.
(golint, vet, errcheck, deadcode, etc..) and shows the warnings/errors
* Lint your code with `:GoLint`
* Run your code through `:GoVet` to catch static errors
* Advanced source analysis tools utilizing oracle, such as `:GoImplements`,
* Advanced source analysis tools utilizing guru, such as `:GoImplements`,
`:GoCallees`, and `:GoReferrers`
* Precise type-safe renaming of identifiers with `:GoRename`
* List all source files and dependencies
@ -226,8 +226,8 @@ CTRL-]
navigate software. For more information on displaying the stack, see
|:GoDefJump|
*:GoDefJump*
:GoDefJump [number]
*:GoDefStack*
:GoDefStack [number]
This command Jumps to a given location in the jumpstack, retaining all other
entries. Jumps to non-existent entries will print an informative message,
@ -251,6 +251,11 @@ CTRL-]
Jumps to non-existent entries will print an informative message, but are
otherwise a noop.
*:GoDefStackClear*
:GoDefStackClear
Clears the current stack list and resets it.
*:GoDefPop*
:GoDefPop [count]
CTRL-t
@ -382,10 +387,23 @@ CTRL-t
:GoCoverage[!] [options]
Create a coverage profile and annotates the current file's source code. If
called again clears the annotation (works as a toggle)
called again it rerurns the tests.
If [!] is not given the first error is jumped to.
*:GoCoverageToggle*
:GoCoverageToggle[!] [options]
Create a coverage profile and annotates the current file's source code. If
called again clears the annotation (works as a toggle).
If [!] is not given the first error is jumped to.
*:GoCoverageClear*
:GoCoverageClear [options]
Clears the coverage annotation.
*:GoCoverageBrowser*
:GoCoverageBrowser[!] [options]
@ -445,13 +463,29 @@ CTRL-t
If [!] is not given the first error is jumped to.
*:GoOracleScope*
:GoOracleScope [path1] [path2] ...
*:GoGuruScope*
:GoGuruScope [pattern] [pattern2] ... [patternN]
Changes the custom |g:go_oracle_scope| setting and overrides it with the
given import paths. The custom scope is cleared (unset) if `""` is given
as the only path. If no arguments is given it prints the current custom
scope.
Changes the custom |g:go_guru_scope| setting and overrides it with the
given package patterns. The custom scope is cleared (unset) if `""` is
given as the only path. If no arguments is given it prints the current
custom scope. Example patterns are:
>
golang.org/x/tools/cmd/guru # a single package
golang.org/x/tools/... # all packages beneath dir
... # the entire workspace.
<
Example usage, the following sets the scope to a `github.com/fatih/color`
and to all packages under `golang.org/x/tools/`:
>
:GoGuruScope github.com/fatih/color golang.org/x/tools/...
<
The following sets it to the entire workspace:
>
:GoGuruScope ...
<
Under the hood, the patterns are all joined to a comma-separated list and
passed to `guru`'s `-scope` flag.
*:GoCallees*
:GoCallees
@ -474,7 +508,7 @@ CTRL-t
type (for an expression), its value (for a constant expression), its size,
alignment, method set and interfaces (for a type), its declaration (for an
identifier), etc. Almost any piece of syntax may be described, and the
oracle will try to print all the useful information it can.
guru will try to print all the useful information it can.
*:GoCallstack*
:GoCallstack
@ -527,10 +561,10 @@ CTRL-t
the variable |g:go_metalinter_command|. To override the maximum linters
execution time use |g:go_metalinter_deadline| variable.
*:GoOracleTags*
:GoOracleTags [tags]
*:GoGuruTags*
:GoGuruTags [tags]
Changes the custom |g:go_oracle_tags| setting and overrides it with the
Changes the custom |g:go_guru_tags| setting and overrides it with the
given build tags. This command cooperate with GoReferrers command when
there exist mulitiple build tags in your project, then you can set one
of the build tags for GoReferrers to find more accurate.
@ -585,12 +619,24 @@ CTRL-t
definitions. By default set to: `"func,type"`. Possible options are:
`{func,type}`
*:GoImpl*
:GoImpl [receiver] [interface]
Generates method stubs for implementing an interface. If no arguments is
passed it takes the identifier under the cursor to be the receiver and
asks for the interface type to be generated. If used with arguments, the
receiver and the interface needs to be specified. Example usages:
>
:GoImpl f *Foo io.Writer
:GoImpl T io.ReadWriteCloser
<
===============================================================================
MAPPINGS *go-mappings*
vim-go has several <Plug> keys which can be used to create custom mappings
For example, to create a mapping that `go run` the current file create a
mapping for the `(go-run)`: >
For example, to create a mapping that `go run` for the current package, create
a mapping for the `(go-run)`: >
au FileType go nmap <leader>r <Plug>(go-run)
@ -600,7 +646,7 @@ documentation in the |go-commands| section. Available <Plug> keys are:
*(go-run)*
Calls `go run` for the current file
Calls `go run` for the current main package
*(go-run-tab)*
@ -651,7 +697,18 @@ Calls `go test -c` for the current package
*(go-coverage)*
Calls `go test -coverprofile-temp.out` for the current package
Calls `go test -coverprofile-temp.out` for the current package and shows the
coverage annotation.
*(go-coverage-clear)*
Clears the coverage annotation
*(go-coverage-toggle)*
Calls `go test -coverprofile-temp.out` for the current package and shows the
coverage annotation. If run agains it acts as a toggle and clears the
annotation.
*(go-vet)*
@ -699,23 +756,36 @@ Goto declaration/definition. Results are shown in the current buffer.
*(go-def-split)*
Goto declaration/definition. Results are shown in a split window.
Goto declaration/definition. Results are shown in a split window.
Jumps to an existing buffer if |g:go_def_reuse_buffer| is enabled.
*(go-def-vertical)*
Goto declaration/definition. Results are shown in a vertical split window.
Jumps to an existing buffer if |g:go_def_reuse_buffer| is enabled.
*(go-def-tab)*
Goto declaration/definition. Results are shown in a tab window.
Jumps to an existing buffer if |g:go_def_reuse_buffer| is enabled.
*(go-implements)*
*(go-def-stack)*
Shows the godef tag stack
*(go-def-stack-clear)*
Resets and clers the tasg stack
*(go-def-pop)*
Jump to previous entry in the tag stack
*(go-implements)*
Show the interfaces that the type under the cursor implements.
*(go-rename)*
*(go-rename)*
Rename the identifier under the cursor to the desired new name
@ -912,6 +982,14 @@ these keys or mappings. Default is enabled. >
let g:go_def_mapping_enabled = 1
<
*'g:go_def_reuse_buffer'*
Use this option to jump to an existing buffer for the split, vsplit and tab
mappings of |:GoDef|. By default it's disabled. >
let g:go_def_reuse_buffer = 0
<
*'g:go_dispatch_enabled'*
Use this option to enable/disable the use of Dispatch to execute the
@ -950,16 +1028,16 @@ is used. Use "neosnippet" for neosnippet.vim: >
let g:go_snippet_engine = "ultisnips"
<
*'g:go_oracle_scope'*
*'g:go_guru_scope'*
Use this option to define the scope of the analysis to be passed for oracle
related commands, such as |GoImplements|, |GoCallers|, etc. By default it's
not set, so only the current package's go files are passed as scope. You can
change it on-the-fly with |GoOracleScope|. For more info, please have a look
at oracle's user manual:
https://golang.org/s/oracle-user-manual#heading=h.nwso96pj07q8 >
let g:go_oracle_scope = ''
Use this option to define the scope of the analysis to be passed for guru
related commands, such as |GoImplements|, |GoCallers|, etc.You can change it
on-the-fly with |GoGuruScope|. The input should be a a list of package
pattern. An example input might be:
`["github.com/fatih/color","github.com/fatih/structs"]` By default it's not set,
so the relevant commands defaults are being used.
>
let g:go_guru_scope = []
<
*'g:go_highlight_array_whitespace_error'*
@ -1216,7 +1294,7 @@ You'll see a more detailed error. If this works, vim-go will work too.
CREDITS *go-credits*
* Go Authors for official vim plugins
* Gocode, Godef, Golint, Oracle, Goimports, Errcheck projects and authors of
* Gocode, Godef, Golint, Guru, Goimports, Errcheck projects and authors of
those projects.
* Other vim-plugins, thanks for inspiration (vim-golang, go.vim, vim-gocode,
vim-godef)

View File

@ -29,9 +29,13 @@ if get(g:, "go_doc_keywordprg_enabled", 1)
endif
if get(g:, "go_def_mapping_enabled", 1)
nnoremap <buffer> <silent> gd :GoDef<cr>
nnoremap <buffer> <silent> <C-]> :GoDef<cr>
nnoremap <buffer> <silent> <C-t> :<C-U>call go#def#StackPop(v:count1)<cr>
" these are default Vim mappings, we're overriding them to make them
" useful again for Go source code
nnoremap <buffer> <silent> gd :GoDef<cr>
nnoremap <buffer> <silent> <C-]> :GoDef<cr>
nnoremap <buffer> <silent> <C-w><C-]> :<C-u>call go#def#Jump("split")<CR>
nnoremap <buffer> <silent> <C-w>] :<C-u>call go#def#Jump("split")<CR>
nnoremap <buffer> <silent> <C-t> :<C-U>call go#def#StackPop(v:count1)<cr>
endif
if get(g:, "go_textobj_enabled", 1)

View File

@ -1,24 +1,27 @@
" gorename
" -- gorename
command! -nargs=? GoRename call go#rename#Rename(<bang>0,<f-args>)
" oracle
command! -nargs=* -complete=customlist,go#package#Complete GoOracleScope call go#oracle#Scope(<f-args>)
command! -range=% GoImplements call go#oracle#Implements(<count>)
command! -range=% GoCallees call go#oracle#Callees(<count>)
command! -range=% GoDescribe call go#oracle#Describe(<count>)
command! -range=% GoCallers call go#oracle#Callers(<count>)
command! -range=% GoCallstack call go#oracle#Callstack(<count>)
command! -range=% GoFreevars call go#oracle#Freevars(<count>)
command! -range=% GoChannelPeers call go#oracle#ChannelPeers(<count>)
command! -range=% GoReferrers call go#oracle#Referrers(<count>)
command! -nargs=? GoOracleTags call go#oracle#Tags(<f-args>)
" -- guru
command! -nargs=* -complete=customlist,go#package#Complete GoGuruScope call go#guru#Scope(<f-args>)
command! -range=% GoImplements call go#guru#Implements(<count>)
command! -range=% GoCallees call go#guru#Callees(<count>)
command! -range=% GoDescribe call go#guru#Describe(<count>)
command! -range=% GoCallers call go#guru#Callers(<count>)
command! -range=% GoCallstack call go#guru#Callstack(<count>)
command! -range=% GoFreevars call go#guru#Freevars(<count>)
command! -range=% GoChannelPeers call go#guru#ChannelPeers(<count>)
command! -range=% GoReferrers call go#guru#Referrers(<count>)
command! -nargs=? GoGuruTags call go#guru#Tags(<f-args>)
" tool
" TODO(arslan): enable this once the function is implemented
" command! -range=% GoSameIds call go#guru#SameIds(<count>)
" -- tool
command! -nargs=0 GoFiles echo go#tool#Files()
command! -nargs=0 GoDeps echo go#tool#Deps()
command! -nargs=* GoInfo call go#complete#Info(0)
" cmd
" -- cmd
command! -nargs=* -bang GoBuild call go#cmd#Build(<bang>0,<f-args>)
command! -nargs=* -bang GoGenerate call go#cmd#Generate(<bang>0,<f-args>)
command! -nargs=* -bang -complete=file GoRun call go#cmd#Run(<bang>0,<f-args>)
@ -29,15 +32,18 @@ command! -nargs=* -bang GoTestCompile call go#cmd#Test(<bang>0, 1, <f-args>)
" -- cover
command! -nargs=* -bang GoCoverage call go#coverage#Buffer(<bang>0, <f-args>)
command! -nargs=* -bang GoCoverageClear call go#coverage#Clear()
command! -nargs=* -bang GoCoverageToggle call go#coverage#BufferToggle(<bang>0, <f-args>)
command! -nargs=* -bang GoCoverageBrowser call go#coverage#Browser(<bang>0, <f-args>)
" -- play
command! -nargs=0 -range=% GoPlay call go#play#Share(<count>, <line1>, <line2>)
" -- def
command! -nargs=* -range GoDef :call go#def#Jump(<f-args>)
command! -nargs=* -range GoDef :call go#def#Jump('')
command! -nargs=? GoDefPop :call go#def#StackPop(<f-args>)
command! -nargs=? GoDefJump :call go#def#StackJump(<f-args>)
command! -nargs=? GoDefStack :call go#def#Stack(<f-args>)
command! -nargs=? GoDefStackClear :call go#def#StackClear(<f-args>)
" -- doc
command! -nargs=* -range -complete=customlist,go#package#Complete GoDoc call go#doc#Open('new', 'split', <f-args>)
@ -67,4 +73,7 @@ if globpath(&rtp, 'plugin/ctrlp.vim') != ""
command! -nargs=? -complete=dir GoDeclsDir call ctrlp#init(ctrlp#decls#cmd(1, <q-args>))
endif
" -- impl
command! -nargs=* -buffer -complete=customlist,go#impl#Complete GoImpl call go#impl#Impl(<f-args>)
" vim:ts=4:sw=4:et

View File

@ -25,6 +25,8 @@ nnoremap <silent> <Plug>(go-test-func) :<C-u>call go#cmd#TestFunc(!g:go_jump_to_
nnoremap <silent> <Plug>(go-test-compile) :<C-u>call go#cmd#Test(!g:go_jump_to_error, 1)<CR>
nnoremap <silent> <Plug>(go-coverage) :<C-u>call go#coverage#Buffer(!g:go_jump_to_error)<CR>
nnoremap <silent> <Plug>(go-coverage-clear) :<C-u>call go#coverage#Clear()<CR>
nnoremap <silent> <Plug>(go-coverage-toggle) :<C-u>call go#coverage#BufferToggle(!g:go_jump_to_error)<CR>
nnoremap <silent> <Plug>(go-coverage-browser) :<C-u>call go#coverage#Browser(!g:go_jump_to_error)<CR>
nnoremap <silent> <Plug>(go-files) :<C-u>call go#tool#Files()<CR>
@ -32,21 +34,28 @@ nnoremap <silent> <Plug>(go-deps) :<C-u>call go#tool#Deps()<CR>
nnoremap <silent> <Plug>(go-info) :<C-u>call go#complete#Info(0)<CR>
nnoremap <silent> <Plug>(go-import) :<C-u>call go#import#SwitchImport(1, '', expand('<cword>'), '')<CR>
nnoremap <silent> <Plug>(go-implements) :<C-u>call go#oracle#Implements(-1)<CR>
nnoremap <silent> <Plug>(go-callees) :<C-u>call go#oracle#Callees(-1)<CR>
nnoremap <silent> <Plug>(go-callers) :<C-u>call go#oracle#Callers(-1)<CR>
nnoremap <silent> <Plug>(go-describe) :<C-u>call go#oracle#Describe(-1)<CR>
nnoremap <silent> <Plug>(go-callstack) :<C-u>call go#oracle#Callstack(-1)<CR>
nnoremap <silent> <Plug>(go-freevars) :<C-u>call go#oracle#Freevars(-1)<CR>
nnoremap <silent> <Plug>(go-channelpeers) :<C-u>call go#oracle#ChannelPeers(-1)<CR>
nnoremap <silent> <Plug>(go-referrers) :<C-u>call go#oracle#Referrers(-1)<CR>
nnoremap <silent> <Plug>(go-implements) :<C-u>call go#guru#Implements(-1)<CR>
nnoremap <silent> <Plug>(go-callees) :<C-u>call go#guru#Callees(-1)<CR>
nnoremap <silent> <Plug>(go-callers) :<C-u>call go#guru#Callers(-1)<CR>
nnoremap <silent> <Plug>(go-describe) :<C-u>call go#guru#Describe(-1)<CR>
nnoremap <silent> <Plug>(go-callstack) :<C-u>call go#guru#Callstack(-1)<CR>
xnoremap <silent> <Plug>(go-freevars) :<C-u>call go#guru#Freevars(0)<CR>
nnoremap <silent> <Plug>(go-channelpeers) :<C-u>call go#guru#ChannelPeers(-1)<CR>
nnoremap <silent> <Plug>(go-referrers) :<C-u>call go#guru#Referrers(-1)<CR>
" TODO(arslan): enable this once the function is implemented
" nnoremap <silent> <Plug>(go-sameids) :<C-u>call go#guru#SameIds(-1)<CR>
nnoremap <silent> <Plug>(go-rename) :<C-u>call go#rename#Rename(!g:go_jump_to_error)<CR>
nnoremap <silent> <Plug>(go-def) :<C-u>call go#def#Jump()<CR>
nnoremap <silent> <Plug>(go-def-vertical) :<C-u>call go#def#JumpMode("vsplit")<CR>
nnoremap <silent> <Plug>(go-def-split) :<C-u>call go#def#JumpMode("split")<CR>
nnoremap <silent> <Plug>(go-def-tab) :<C-u>call go#def#JumpMode("tab")<CR>
nnoremap <silent> <Plug>(go-def) :<C-u>call go#def#Jump('')<CR>
nnoremap <silent> <Plug>(go-def-vertical) :<C-u>call go#def#Jump("vsplit")<CR>
nnoremap <silent> <Plug>(go-def-split) :<C-u>call go#def#Jump("split")<CR>
nnoremap <silent> <Plug>(go-def-tab) :<C-u>call go#def#Jump("tab")<CR>
nnoremap <silent> <Plug>(go-def-pop) :<C-u>call go#def#StackPop()<CR>
nnoremap <silent> <Plug>(go-def-stack) :<C-u>call go#def#Stack()<CR>
nnoremap <silent> <Plug>(go-def-stack-clear) :<C-u>call go#def#StackClear()<CR>
nnoremap <silent> <Plug>(go-doc) :<C-u>call go#doc#Open("new", "split")<CR>
nnoremap <silent> <Plug>(go-doc-tab) :<C-u>call go#doc#Open("tabnew", "tabe")<CR>

View File

@ -0,0 +1,6 @@
if exists("b:did_ftplugin")
finish
endif
let b:did_ftplugin = 1
setlocal commentstring=<!--\ %s\ -->

View File

@ -327,6 +327,18 @@ func Test${1:Function}(t *testing.T) {
}
endsnippet
snippet hf "http.HandlerFunc" !b
func ${1:handler}(w http.ResponseWriter, r *http.Request) {
${0:fmt.Fprintf(w, "hello world")}
}
endsnippet
snippet hhf "mux.HandleFunc" !b
${1:http}.HandleFunc("${2:/}", func(w http.ResponseWriter, r *http.Request) {
${0:fmt.Fprintf(w, "hello world")}
})
endsnippet
# quick test server
snippet tsrv "httptest.NewServer"
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
@ -351,6 +363,21 @@ if err != nil {
}
endsnippet
snippet example "func ExampleXYZ() { ... }"
func Example${1:Method}() {
${0:${VISUAL}}
// Output:
}
endsnippet
snippet benchmark "func BenchmarkXYZ(b *testing.B) { ... }"
func Benchmark${1:Method}(b *testing.B) {
for i := 0; i < b.N; i++ {
${0:${VISUAL}}
}
}
endsnippet
# variable declaration
snippet var "var x Type [= ...]"
var ${1:x} ${2:Type}${3: = ${0:value}}
@ -372,7 +399,6 @@ if !reflect.DeepEqual(${1:expected}, ${2:actual}) {
}
endsnippet
global !p
import re

View File

@ -305,6 +305,21 @@ abbr if err != nil { t.Fatalf(...) }
if err != nil {
t.Fatalf("${1}")
}
# test example
snippet example
func Example${1:Method}() {
${0}
// Output:
}
endsnippet
# test benchmark
snippet benchmark
func Benchmark${1:Method}(b *testing.B) {
for i := 0; i < b.N; i++ {
${0}
}
}
endsnippet
# variable declaration
snippet var
abbr var x Type [= ...]
@ -323,3 +338,15 @@ abbr equals: test two identifiers with DeepEqual
fmt.Printf("%s:%d:\n\n\texp: %#v\n\n\tgot: %#v\n\n", filepath.Base(file), line, $1, $2)
t.FailNow()
}
snippet hf
abbr http.HandlerFunc
func ${1:handler}(w http.ResponseWriter, r *http.Request) {
${0:fmt.Fprintf(w, "hello world")}
}
snippet hhf
abbr mux.HandleFunc(...)
${1:http}.HandleFunc("${2:/}", func(w http.ResponseWriter, r *http.Request) {
${0:fmt.Fprintf(w, "hello world")}
})

View File

@ -4,15 +4,13 @@ if exists("g:go_loaded_install")
endif
let g:go_loaded_install = 1
" these packages are used by vim-go and can be automatically installed if
" needed by the user with GoInstallBinaries
let s:packages = [
\ "github.com/nsf/gocode",
\ "github.com/alecthomas/gometalinter",
\ "golang.org/x/tools/cmd/goimports",
\ "github.com/rogpeppe/godef",
\ "golang.org/x/tools/cmd/oracle",
\ "golang.org/x/tools/cmd/guru",
\ "golang.org/x/tools/cmd/gorename",
\ "github.com/golang/lint/golint",
\ "github.com/kisielk/errcheck",
@ -20,6 +18,7 @@ let s:packages = [
\ "github.com/klauspost/asmfmt/cmd/asmfmt",
\ "github.com/fatih/motion",
\ "github.com/zmb3/gogetdoc",
\ "github.com/josharian/impl",
\ ]
" These commands are available on any filetypes
@ -54,7 +53,7 @@ function! s:GoInstallBinaries(updateBinaries)
let old_path = $PATH
" vim's executable path is looking in PATH so add our go_bin path to it
let $PATH = $PATH . go#util#PathListSep() .go_bin_path
let $PATH = go_bin_path . go#util#PathListSep() . $PATH
" when shellslash is set on MS-* systems, shellescape puts single quotes
" around the output string. cmd on Windows does not handle single quotes
@ -68,7 +67,7 @@ function! s:GoInstallBinaries(updateBinaries)
let cmd = "go get -u -v "
let s:go_version = matchstr(system("go version"), '\d.\d.\d')
let s:go_version = matchstr(go#util#System("go version"), '\d.\d.\d')
" https://github.com/golang/go/issues/10791
if s:go_version > "1.4.0" && s:go_version < "1.5.0"
@ -92,8 +91,8 @@ function! s:GoInstallBinaries(updateBinaries)
endif
let out = system(cmd . shellescape(pkg))
if v:shell_error
let out = go#util#System(cmd . shellescape(pkg))
if go#util#ShellError() != 0
echo "Error installing ". pkg . ": " . out
endif
endif
@ -168,10 +167,6 @@ augroup vim-go
if get(g:, "go_metalinter_autosave", 0)
autocmd BufWritePost *.go call go#lint#Gometa(1)
endif
" initialize window-local godef stack
au BufReadPre,WinEnter *.go if !exists('w:go_stack') | let w:go_stack = [] | endif
au BufReadPre,WinEnter *.go if !exists('w:go_stack_level') | let w:go_stack_level = 0 | endif
augroup END