Merge commit '3db97158a41b534758a2262cfdaa0eff37ec6ed2' as 'vim/bundle/go'
commit
3660c961af
@ -0,0 +1 @@
|
||||
doc/tags
|
@ -0,0 +1,276 @@
|
||||
# vim-go
|
||||
|
||||
Go (golang) support for Vim. It comes with pre-defined sensible settings (like
|
||||
auto gofmt on save), has autocomplete, snippet support, improved syntax
|
||||
highlighting, go toolchain commands, etc... If needed vim-go installs all
|
||||
necessary binaries for providing seamless Vim integration with current
|
||||
commands. It's highly customizable and each individual feature can be
|
||||
disabled/enabled easily.
|
||||
|
||||
![vim-go](https://dl.dropboxusercontent.com/u/174404/vim-go-2.png)
|
||||
|
||||
## Features
|
||||
|
||||
* Improved Syntax highlighting, such as Functions, Operators, Methods..
|
||||
* Auto completion support via `gocode`
|
||||
* Better `gofmt` on save, keeps cursor position and doesn't break your undo
|
||||
history
|
||||
* Go to symbol/declaration with `godef`
|
||||
* Look up documentation with `godoc` inside Vim or open it in browser.
|
||||
* Automatically import packages via `goimports`
|
||||
* Compile and `go build` your package, install it with `go install`
|
||||
* `go run` quickly your current file/files
|
||||
* Run `go test` and see any errors in quickfix window
|
||||
* Create a coverage profile and display annotated source code in browser to see
|
||||
which functions are covered.
|
||||
* Lint your code with `golint`
|
||||
* Run your code through `go vet` to catch static errors.
|
||||
* Advanced source analysis tool with `oracle`
|
||||
* Precise type-safe renaming of identifiers with `gorename`
|
||||
* List all source files and dependencies
|
||||
* Checking with `errcheck` for unchecked errors.
|
||||
* Integrated and improved snippets. Supports `ultisnips` or `neosnippet`
|
||||
* Share your current code to [play.golang.org](http://play.golang.org)
|
||||
* On-the-fly type information about the word under the cursor
|
||||
* Tagbar support to show tags of the source code in a sidebar with `gotags`
|
||||
|
||||
## Install
|
||||
|
||||
First of all, do not use it with other Go plugins. If you use pathogen, just
|
||||
clone it into your bundle directory:
|
||||
|
||||
```bash
|
||||
$ cd ~/.vim/bundle
|
||||
$ git clone https://github.com/fatih/vim-go.git
|
||||
```
|
||||
|
||||
For Vundle add this line to your vimrc:
|
||||
|
||||
```vimrc
|
||||
Plugin 'fatih/vim-go'
|
||||
```
|
||||
and execute `:PluginInstall` (or `:BundleInstall` for older versions of Vundle)
|
||||
|
||||
Please be sure all necessary binaries are installed (such as `gocode`, `godef`,
|
||||
`goimports`, etc..). You can easily install them with the included
|
||||
`:GoInstallBinaries`. Those binaries will be automatically downloaded and
|
||||
installed to your `$GOBIN` environment (if not set it will use `$GOPATH/bin`).
|
||||
It requires `git` and `hg` for fetching the individual Go packages.
|
||||
|
||||
### Optional
|
||||
|
||||
* Autocompletion is enabled by default via `<C-x><C-o>`, to get real-time
|
||||
completion (completion by type) install:
|
||||
[YCM](https://github.com/Valloric/YouCompleteMe) or
|
||||
[neocomplete](https://github.com/Shougo/neocomplete.vim).
|
||||
* To get displayed source code tag informations on a sidebar install
|
||||
[tagbar](https://github.com/majutsushi/tagbar).
|
||||
* For snippet feature install:
|
||||
[ultisnips](https://github.com/SirVer/ultisnips) or
|
||||
[neosnippet](https://github.com/Shougo/neosnippet.vim).
|
||||
* Screenshot color scheme is a slightly modified molokai: [fatih/molokai](https://github.com/fatih/molokai).
|
||||
|
||||
## Usage
|
||||
|
||||
All [features](#features) are enabled by default. There are no additional
|
||||
settings needed. Usage and commands are listed in `doc/vim-go.txt`. Just open
|
||||
the help page to see all commands:
|
||||
|
||||
:help vim-go
|
||||
|
||||
## Mappings
|
||||
|
||||
vim-go has several `<Plug>` mappings which can be used to create custom
|
||||
mappings. Below are some examples you might find useful:
|
||||
|
||||
Show a list of interfaces which is implemented by the type under your cursor
|
||||
with `<leader>s`
|
||||
|
||||
```vim
|
||||
au FileType go nmap <Leader>s <Plug>(go-implements)
|
||||
```
|
||||
|
||||
Show type info for the word under your cursor with `<leader>i` (useful if you
|
||||
have disabled auto showing type info via `g:go_auto_type_info`)
|
||||
|
||||
```vim
|
||||
au FileType go nmap <Leader>i <Plug>(go-info)
|
||||
```
|
||||
|
||||
Open the relevant Godoc for the word under the cursor with `<leader>gd` or open
|
||||
it vertically with `<leader>gv`
|
||||
|
||||
```vim
|
||||
au FileType go nmap <Leader>gd <Plug>(go-doc)
|
||||
au FileType go nmap <Leader>gv <Plug>(go-doc-vertical)
|
||||
```
|
||||
|
||||
Or open the Godoc in browser
|
||||
|
||||
```vim
|
||||
au FileType go nmap <Leader>gb <Plug>(go-doc-browser)
|
||||
```
|
||||
|
||||
Run commands, such as `go run` with `<leader>r` for the current file or `go
|
||||
build` and `go test` for the current package with `<leader>b` and `<leader>t`.
|
||||
Display a beautiful annotated source code to see which functions are covered
|
||||
with `<leader>c`.
|
||||
|
||||
```vim
|
||||
au FileType go nmap <leader>r <Plug>(go-run)
|
||||
au FileType go nmap <leader>b <Plug>(go-build)
|
||||
au FileType go nmap <leader>t <Plug>(go-test)
|
||||
au FileType go nmap <leader>c <Plug>(go-coverage)
|
||||
```
|
||||
|
||||
By default the mapping `gd` is enabled which opens the target identifier in
|
||||
current buffer. You can also open the definition/declaration in a new vertical,
|
||||
horizontal or tab for the word under your cursor:
|
||||
|
||||
```vim
|
||||
au FileType go nmap <Leader>ds <Plug>(go-def-split)
|
||||
au FileType go nmap <Leader>dv <Plug>(go-def-vertical)
|
||||
au FileType go nmap <Leader>dt <Plug>(go-def-tab)
|
||||
```
|
||||
|
||||
Rename the identifier under the cursor to a new name
|
||||
|
||||
```vim
|
||||
au FileType go nmap <Leader>e <Plug>(go-rename)
|
||||
```
|
||||
|
||||
More `<Plug>` mappings can be seen with `:he go-mappings`. Also these are just
|
||||
recommendations, you are free to create more advanced mappings or functions
|
||||
based on `:he go-commands`.
|
||||
|
||||
## Settings
|
||||
Below are some settings you might find useful. For the full list see `:he go-settings`.
|
||||
|
||||
Disable opening browser after posting to your snippet to `play.golang.org`:
|
||||
|
||||
```vim
|
||||
let g:go_play_open_browser = 0
|
||||
```
|
||||
|
||||
By default vim-go shows errors for the fmt command, to disable it:
|
||||
|
||||
```vim
|
||||
let g:go_fmt_fail_silently = 1
|
||||
```
|
||||
|
||||
Enable goimports to automatically insert import paths instead of gofmt:
|
||||
|
||||
```vim
|
||||
let g:go_fmt_command = "goimports"
|
||||
```
|
||||
|
||||
Disable auto fmt on save:
|
||||
|
||||
```vim
|
||||
let g:go_fmt_autosave = 0
|
||||
```
|
||||
|
||||
By default binaries are installed to `$GOBIN` or `$GOPATH/bin`. To change it:
|
||||
|
||||
```vim
|
||||
let g:go_bin_path = expand("~/.gotools")
|
||||
let g:go_bin_path = "/home/fatih/.mypath" "or give absolute path
|
||||
```
|
||||
|
||||
By default syntax-highlighting for Functions, Methods and Structs is disabled.
|
||||
To change it:
|
||||
```vim
|
||||
let g:go_highlight_functions = 1
|
||||
let g:go_highlight_methods = 1
|
||||
let g:go_highlight_structs = 1
|
||||
```
|
||||
|
||||
## Snippets
|
||||
|
||||
Snippets are useful and very powerful. By default ultisnips is
|
||||
used, however you can change it to neosnippet with:
|
||||
|
||||
```vim
|
||||
let g:go_snippet_engine = "neosnippet"
|
||||
```
|
||||
|
||||
Snippet feature is enabled only if the snippet plugins are installed. Below are
|
||||
some examples snippets and the corresponding trigger keywords, The `|`
|
||||
character defines the cursor. Ultisnips has support for multiple cursors
|
||||
|
||||
|
||||
`ff` is useful for debugging:
|
||||
|
||||
```go
|
||||
fmt.Printf(" | %+v\n", |)
|
||||
```
|
||||
|
||||
`errn` expands to:
|
||||
|
||||
```go
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
```
|
||||
|
||||
Use `gof` to quickly create a anonymous goroutine :
|
||||
|
||||
```go
|
||||
go func() {
|
||||
|
|
||||
}()
|
||||
```
|
||||
|
||||
To add `json` tags to a struct field, use `json` trigger:
|
||||
|
||||
```
|
||||
type foo struct {
|
||||
bar string `json:"myField"
|
||||
^ type `json` here, hit tab and type "myField". It will expand to `json:"myField"`
|
||||
}
|
||||
```
|
||||
|
||||
...
|
||||
|
||||
And many more! For the full list have a look at the
|
||||
[included snippets](https://github.com/fatih/vim-go/blob/master/gosnippets/):
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### I'm using Fish shell but have some problems using Vim-go
|
||||
|
||||
First environment variables in Fish are applied differently, it should be like:
|
||||
|
||||
set -x GOPATH /your/own/gopath
|
||||
|
||||
Second, Vim needs a POSIX compatible shell (more info here:
|
||||
https://github.com/dag/vim-fish#teach-a-vim-to-fish). If you use Fish to open
|
||||
vim, it will make certain shell based commands fail (means vim-go will fail
|
||||
too). To overcome this problem change the default shell by adding the following
|
||||
into your .vimrc (on the top of the file):
|
||||
|
||||
if $SHELL =~ 'fish'
|
||||
set shell='/bin/bash'
|
||||
endif
|
||||
|
||||
or
|
||||
|
||||
set shell='/bin/bash'
|
||||
|
||||
|
||||
## Why another plugin?
|
||||
|
||||
This plugin/package is born mainly from frustration. I had to re-install my Vim
|
||||
plugins and especially for Go I had to install a lot of separate different
|
||||
plugins, setup the necessary binaries to make them work together and hope not
|
||||
to lose them again. Lots of plugins out there lack proper settings.
|
||||
This plugin is improved and contains all my fixes/changes that I'm using for
|
||||
months under heavy go development environment.
|
||||
|
||||
Give it a try. I hope you like it. Feel free to contribute to the project.
|
||||
|
||||
## Credits
|
||||
|
||||
* Go Authors for official vim plugins
|
||||
* Gocode, Godef, Golint, Oracle, Goimports, Gotags, Errcheck projects and authors of those projects.
|
||||
* Other vim-plugins, thanks for inspiration (vim-golang, go.vim, vim-gocode, vim-godef)
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "vim-go",
|
||||
"description": "Full featured Go (golang) support for Vim.",
|
||||
"author": "Fatih Arslan <fatih@arslan.io>",
|
||||
"repository" : {"type": "git", "url": "https://github.com/fatih/vim-go.git"}
|
||||
}
|
@ -0,0 +1,157 @@
|
||||
if !exists("g:go_jump_to_error")
|
||||
let g:go_jump_to_error = 1
|
||||
endif
|
||||
|
||||
function! go#cmd#Run(bang, ...)
|
||||
let goFiles = '"' . join(go#tool#Files(), '" "') . '"'
|
||||
|
||||
if IsWin()
|
||||
exec '!go run ' . goFiles
|
||||
if v:shell_error
|
||||
redraws! | echon "vim-go: [run] " | echohl ErrorMsg | echon "FAILED"| echohl None
|
||||
else
|
||||
redraws! | echon "vim-go: [run] " | echohl Function | echon "SUCCESS"| echohl None
|
||||
endif
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
let default_makeprg = &makeprg
|
||||
if !len(a:000)
|
||||
let &makeprg = 'go run ' . goFiles
|
||||
else
|
||||
let &makeprg = "go run " . expand(a:1)
|
||||
endif
|
||||
|
||||
exe 'make!'
|
||||
if !a:bang
|
||||
cwindow
|
||||
let errors = getqflist()
|
||||
if !empty(errors)
|
||||
if g:go_jump_to_error
|
||||
cc 1 "jump to first error if there is any
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
let &makeprg = default_makeprg
|
||||
endfunction
|
||||
|
||||
function! go#cmd#Install(...)
|
||||
let pkgs = join(a:000, '" "')
|
||||
let command = 'go install "' . pkgs . '"'
|
||||
let out = go#tool#ExecuteInDir(command)
|
||||
if v:shell_error
|
||||
call go#tool#ShowErrors(out)
|
||||
cwindow
|
||||
return
|
||||
endif
|
||||
|
||||
if exists("$GOBIN")
|
||||
echon "vim-go: " | echohl Function | echon "installed to ". $GOBIN | echohl None
|
||||
else
|
||||
echon "vim-go: " | echohl Function | echon "installed to ". $GOPATH . "/bin" | echohl None
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! go#cmd#Build(bang, ...)
|
||||
let default_makeprg = &makeprg
|
||||
let gofiles = join(go#tool#Files(), '" "')
|
||||
if v:shell_error
|
||||
let &makeprg = "go build . errors"
|
||||
else
|
||||
let &makeprg = "go build -o /dev/null " . join(a:000, ' ') . ' "' . gofiles . '"'
|
||||
endif
|
||||
|
||||
echon "vim-go: " | echohl Identifier | echon "building ..."| echohl None
|
||||
silent! exe 'make!'
|
||||
redraw!
|
||||
if !a:bang
|
||||
cwindow
|
||||
let errors = getqflist()
|
||||
if !empty(errors)
|
||||
if g:go_jump_to_error
|
||||
cc 1 "jump to first error if there is any
|
||||
endif
|
||||
else
|
||||
redraws! | echon "vim-go: " | echohl Function | echon "[build] SUCCESS"| echohl None
|
||||
endif
|
||||
endif
|
||||
|
||||
let &makeprg = default_makeprg
|
||||
endfunction
|
||||
|
||||
function! go#cmd#Test(...)
|
||||
let command = "go test ."
|
||||
if len(a:000)
|
||||
let command = "go test " . expand(a:1)
|
||||
endif
|
||||
|
||||
echon "vim-go: " | echohl Identifier | echon "testing ..." | echohl None
|
||||
let out = go#tool#ExecuteInDir(command)
|
||||
if v:shell_error
|
||||
call go#tool#ShowErrors(out)
|
||||
else
|
||||
call setqflist([])
|
||||
endif
|
||||
cwindow
|
||||
|
||||
let errors = getqflist()
|
||||
if !empty(errors)
|
||||
if g:go_jump_to_error
|
||||
cc 1 "jump to first error if there is any
|
||||
endif
|
||||
else
|
||||
redraw | echon "vim-go: " | echohl Function | echon "[test] PASS" | echohl None
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! go#cmd#Coverage(...)
|
||||
let l:tmpname=tempname()
|
||||
|
||||
let command = "go test -coverprofile=".l:tmpname
|
||||
|
||||
let out = go#tool#ExecuteInDir(command)
|
||||
if v:shell_error
|
||||
call go#tool#ShowErrors(out)
|
||||
else
|
||||
" clear previous quick fix window
|
||||
call setqflist([])
|
||||
|
||||
let openHTML = 'go tool cover -html='.l:tmpname
|
||||
call go#tool#ExecuteInDir(openHTML)
|
||||
endif
|
||||
cwindow
|
||||
|
||||
let errors = getqflist()
|
||||
if !empty(errors)
|
||||
if g:go_jump_to_error
|
||||
cc 1 "jump to first error if there is any
|
||||
endif
|
||||
endif
|
||||
|
||||
call delete(l:tmpname)
|
||||
endfunction
|
||||
|
||||
function! go#cmd#Vet()
|
||||
echon "vim-go: " | echohl Identifier | echon "calling vet..." | echohl None
|
||||
let out = go#tool#ExecuteInDir('go vet')
|
||||
if v:shell_error
|
||||
call go#tool#ShowErrors(out)
|
||||
else
|
||||
call setqflist([])
|
||||
endif
|
||||
cwindow
|
||||
|
||||
let errors = getqflist()
|
||||
if !empty(errors)
|
||||
if g:go_jump_to_error
|
||||
cc 1 "jump to first error if there is any
|
||||
endif
|
||||
else
|
||||
redraw | echon "vim-go: " | echohl Function | echon "[vet] PASS" | echohl None
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" vim:ts=4:sw=4:et
|
||||
"
|
@ -0,0 +1,144 @@
|
||||
if !exists("g:go_gocode_bin")
|
||||
let g:go_gocode_bin = "gocode"
|
||||
endif
|
||||
|
||||
|
||||
fu! s:gocodeCurrentBuffer()
|
||||
let buf = getline(1, '$')
|
||||
if &encoding != 'utf-8'
|
||||
let buf = map(buf, 'iconv(v:val, &encoding, "utf-8")')
|
||||
endif
|
||||
if &l:fileformat == 'dos'
|
||||
" XXX: line2byte() depend on 'fileformat' option.
|
||||
" so if fileformat is 'dos', 'buf' must include '\r'.
|
||||
let buf = map(buf, 'v:val."\r"')
|
||||
endif
|
||||
let file = tempname()
|
||||
call writefile(buf, file)
|
||||
|
||||
return file
|
||||
endf
|
||||
|
||||
let s:vim_system = get(g:, 'gocomplete#system_function', 'system')
|
||||
|
||||
fu! s:system(str, ...)
|
||||
return call(s:vim_system, [a:str] + a:000)
|
||||
endf
|
||||
|
||||
fu! s:gocodeShellescape(arg)
|
||||
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])
|
||||
endfor
|
||||
for i in range(0, len(a:preargs) - 1)
|
||||
let a:preargs[i] = s:gocodeShellescape(a:preargs[i])
|
||||
endfor
|
||||
|
||||
let bin_path = go#tool#BinPath(g:go_gocode_bin)
|
||||
if empty(bin_path)
|
||||
return
|
||||
endif
|
||||
|
||||
let result = s:system(printf('%s %s %s %s', bin_path, join(a:preargs), a:cmd, join(a:args)))
|
||||
if v:shell_error != 0
|
||||
return "[\"0\", []]"
|
||||
else
|
||||
if &encoding != 'utf-8'
|
||||
let result = iconv(result, 'utf-8', &encoding)
|
||||
endif
|
||||
return result
|
||||
endif
|
||||
endf
|
||||
|
||||
fu! s:gocodeCurrentBufferOpt(filename)
|
||||
return '-in=' . a:filename
|
||||
endf
|
||||
|
||||
fu! s:gocodeCursor()
|
||||
if &encoding != 'utf-8'
|
||||
let sep = &l:fileformat == 'dos' ? "\r\n" : "\n"
|
||||
let c = col('.')
|
||||
let buf = line('.') == 1 ? "" : (join(getline(1, line('.')-1), sep) . sep)
|
||||
let buf .= c == 1 ? "" : getline('.')[:c-2]
|
||||
return printf('%d', len(iconv(buf, &encoding, "utf-8")))
|
||||
endif
|
||||
return printf('%d', line2byte(line('.')) + (col('.')-2))
|
||||
endf
|
||||
|
||||
fu! s:gocodeAutocomplete()
|
||||
let filename = s:gocodeCurrentBuffer()
|
||||
let result = s:gocodeCommand('autocomplete',
|
||||
\ [s:gocodeCurrentBufferOpt(filename), '-f=vim'],
|
||||
\ [expand('%:p'), s:gocodeCursor()])
|
||||
call delete(filename)
|
||||
return result
|
||||
endf
|
||||
|
||||
function! go#complete#GetInfo()
|
||||
let filename = s:gocodeCurrentBuffer()
|
||||
let result = s:gocodeCommand('autocomplete',
|
||||
\ [s:gocodeCurrentBufferOpt(filename), '-f=godit'],
|
||||
\ [expand('%:p'), s:gocodeCursor()])
|
||||
call delete(filename)
|
||||
|
||||
" first line is: Charcount,,NumberOfCandidates, i.e: 8,,1
|
||||
" following lines are candiates, i.e: func foo(name string),,foo(
|
||||
let out = split(result, '\n')
|
||||
|
||||
" no candidates are found
|
||||
if len(out) == 1
|
||||
return ""
|
||||
endif
|
||||
|
||||
" only one candiate is found
|
||||
if len(out) == 2
|
||||
return split(out[1], ',,')[0]
|
||||
endif
|
||||
|
||||
" to many candidates are available, pick one that maches the word under the
|
||||
" cursor
|
||||
let infos = []
|
||||
for info in out[1:]
|
||||
call add(infos, split(info, ',,')[0])
|
||||
endfor
|
||||
|
||||
let wordMatch = '\<' . expand("<cword>") . '\>'
|
||||
" escape single quotes in wordMatch before passing it to filter
|
||||
let wordMatch = substitute(wordMatch, "'", "''", "g")
|
||||
let filtered = filter(infos, "v:val =~ '".wordMatch."'")
|
||||
|
||||
if len(filtered) == 1
|
||||
return filtered[0]
|
||||
endif
|
||||
|
||||
return ""
|
||||
endfunction
|
||||
|
||||
function! go#complete#Info()
|
||||
let result = go#complete#GetInfo()
|
||||
if !empty(result)
|
||||
echo "vim-go: " | echohl Function | echon result | echohl None
|
||||
endif
|
||||
endfunction!
|
||||
|
||||
fu! go#complete#Complete(findstart, base)
|
||||
"findstart = 1 when we need to get the text length
|
||||
if a:findstart == 1
|
||||
execute "silent let g:gocomplete_completions = " . s:gocodeAutocomplete()
|
||||
return col('.') - g:gocomplete_completions[0] - 1
|
||||
"findstart = 0 when we need to return the list of completions
|
||||
else
|
||||
return g:gocomplete_completions[1]
|
||||
endif
|
||||
endf
|
||||
|
||||
" vim:ts=4:sw=4:et
|
@ -0,0 +1,105 @@
|
||||
if !exists("g:go_godef_bin")
|
||||
let g:go_godef_bin = "godef"
|
||||
endif
|
||||
|
||||
|
||||
" modified and improved version of vim-godef
|
||||
function! go#def#Jump(...)
|
||||
if !len(a:000)
|
||||
" gives us the offset of the word, basicall the position of the word under
|
||||
" he cursor
|
||||
let arg = s:getOffset()
|
||||
else
|
||||
let arg = a:1
|
||||
endif
|
||||
|
||||
let bin_path = go#tool#BinPath(g:go_godef_bin)
|
||||
if empty(bin_path)
|
||||
return
|
||||
endif
|
||||
|
||||
let command = bin_path . " -f=" . expand("%:p") . " -i " . shellescape(arg)
|
||||
|
||||
" get output of godef
|
||||
let out=system(command, join(getbufline(bufnr('%'), 1, '$'), LineEnding()))
|
||||
|
||||
" jump to it
|
||||
call s:godefJump(out, "")
|
||||
endfunction
|
||||
|
||||
|
||||
function! go#def#JumpMode(mode)
|
||||
let arg = s:getOffset()
|
||||
|
||||
let bin_path = go#tool#BinPath(g:go_godef_bin)
|
||||
if empty(bin_path)
|
||||
return
|
||||
endif
|
||||
|
||||
let command = bin_path . " -f=" . expand("%:p") . " -i " . shellescape(arg)
|
||||
|
||||
" get output of godef
|
||||
let out=system(command, join(getbufline(bufnr('%'), 1, '$'), LineEnding()))
|
||||
|
||||
call s:godefJump(out, a:mode)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:getOffset()
|
||||
let pos = getpos(".")[1:2]
|
||||
if &encoding == 'utf-8'
|
||||
let offs = line2byte(pos[0]) + pos[1] - 2
|
||||
else
|
||||
let c = pos[1]
|
||||
let buf = line('.') == 1 ? "" : (join(getline(1, pos[0] - 1), LineEnding()) . LineEnding())
|
||||
let buf .= c == 1 ? "" : getline(pos[0])[:c-2]
|
||||
let offs = len(iconv(buf, &encoding, "utf-8"))
|
||||
endif
|
||||
|
||||
let argOff = "-o=" . offs
|
||||
return argOff
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:godefJump(out, mode)
|
||||
let old_errorformat = &errorformat
|
||||
let &errorformat = "%f:%l:%c"
|
||||
|
||||
if a:out =~ 'godef: '
|
||||
let out=substitute(a:out, LineEnding() . '$', '', '')
|
||||
echom out
|
||||
else
|
||||
let parts = split(a:out, ':')
|
||||
" parts[0] contains filename
|
||||
let fileName = parts[0]
|
||||
|
||||
" put the error format into location list so we can jump automatically to
|
||||
" it
|
||||
lgetexpr a:out
|
||||
|
||||
" 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
|
||||
else
|
||||
if a:mode == "split"
|
||||
split
|
||||
elseif a:mode == "vsplit"
|
||||
vsplit
|
||||
endif
|
||||
endif
|
||||
|
||||
" jump to file now
|
||||
sil ll 1
|
||||
normal zz
|
||||
|
||||
let &switchbuf = old_switchbuf
|
||||
end
|
||||
let &errorformat = old_errorformat
|
||||
endfunction
|
@ -0,0 +1,163 @@
|
||||
" Copyright 2011 The Go Authors. All rights reserved.
|
||||
" Use of this source code is governed by a BSD-style
|
||||
" license that can be found in the LICENSE file.
|
||||
"
|
||||
" godoc.vim: Vim command to see godoc.
|
||||
"
|
||||
"
|
||||
" Commands:
|
||||
"
|
||||
" :GoDoc
|
||||
"
|
||||
" Open the relevant Godoc for either the word[s] passed to the command or
|
||||
" the, by default, the word under the cursor.
|
||||
"
|
||||
" Options:
|
||||
"
|
||||
" g:go_godoc_commands [default=1]
|
||||
"
|
||||
" Flag to indicate whether to enable the commands listed above.
|
||||
|
||||
let s:buf_nr = -1
|
||||
|
||||
if !exists("g:go_doc_command")
|
||||
let g:go_doc_command = "godoc"
|
||||
endif
|
||||
|
||||
if !exists("g:go_doc_options")
|
||||
let g:go_doc_options = ""
|
||||
endif
|
||||
|
||||
" returns the package and exported name. exported name might be empty.
|
||||
" ie: fmt and Println
|
||||
" ie: github.com/fatih/set and New
|
||||
function! s:godocWord(args)
|
||||
if !executable('godoc')
|
||||
echohl WarningMsg
|
||||
echo "godoc command not found."
|
||||
echo " install with: go get golang.org/x/tools/cmd/godoc"
|
||||
echohl None
|
||||
return []
|
||||
endif
|
||||
|
||||
if !len(a:args)
|
||||
let oldiskeyword = &iskeyword
|
||||
setlocal iskeyword+=.
|
||||
let word = expand('<cword>')
|
||||
let &iskeyword = oldiskeyword
|
||||
let word = substitute(word, '[^a-zA-Z0-9\\/._~-]', '', 'g')
|
||||
let words = split(word, '\.\ze[^./]\+$')
|
||||
else
|
||||
let words = a:args
|
||||
endif
|
||||
|
||||
if !len(words)
|
||||
return []
|
||||
endif
|
||||
|
||||
let pkg = words[0]
|
||||
if len(words) == 1
|
||||
let exported_name = ""
|
||||
else
|
||||
let exported_name = words[1]
|
||||
endif
|
||||
|
||||
let packages = go#tool#Imports()
|
||||
|
||||
if has_key(packages, pkg)
|
||||
let pkg = packages[pkg]
|
||||
endif
|
||||
|
||||
return [pkg, exported_name]
|
||||
endfunction
|
||||
|
||||
function! go#doc#OpenBrowser(...)
|
||||
let pkgs = s:godocWord(a:000)
|
||||
if empty(pkgs)
|
||||
return
|
||||
endif
|
||||
|
||||
let pkg = pkgs[0]
|
||||
let exported_name = pkgs[1]
|
||||
|
||||
" example url: https://godoc.org/github.com/fatih/set#Set
|
||||
let godoc_url = "https://godoc.org/" . pkg . "#" . exported_name
|
||||
call go#tool#OpenBrowser(godoc_url)
|
||||
endfunction
|
||||
|
||||
function! go#doc#Open(mode, ...)
|
||||
let pkgs = s:godocWord(a:000)
|
||||
if empty(pkgs)
|
||||
return
|
||||
endif
|
||||
|
||||
let pkg = pkgs[0]
|
||||
let exported_name = pkgs[1]
|
||||
|
||||
let command = g:go_doc_command . ' ' . g:go_doc_options . ' ' . pkg
|
||||
|
||||
silent! let content = system(command)
|
||||
if v:shell_error || !len(content)
|
||||
echo 'No documentation found for "' . pkg . '".'
|
||||
return -1
|
||||
endif
|
||||
|
||||
call s:GodocView(a:mode, content)
|
||||
|
||||
if exported_name == ''
|
||||
silent! normal gg
|
||||
return -1
|
||||
endif
|
||||
|
||||
" jump to the specified name
|
||||
if search('^func ' . exported_name . '(')
|
||||
silent! normal zt
|
||||
return -1
|
||||
endif
|
||||
|
||||
if search('^type ' . exported_name)
|
||||
silent! normal zt
|
||||
return -1
|
||||
endif
|
||||
|
||||
if search('^\%(const\|var\|type\|\s\+\) ' . pkg . '\s\+=\s')
|
||||
silent! normal zt
|
||||
return -1
|
||||
endif
|
||||
|
||||
" nothing found, jump to top
|
||||
silent! normal gg
|
||||
endfunction
|
||||
|
||||
function! s:GodocView(position, content)
|
||||
" reuse existing buffer window if it exists otherwise create a new one
|
||||
if !bufexists(s:buf_nr)
|
||||
execute a:position
|
||||
sil file `="[Godoc]"`
|
||||
let s:buf_nr = bufnr('%')
|
||||
elseif bufwinnr(s:buf_nr) == -1
|
||||
execute a:position
|
||||
execute s:buf_nr . 'buffer'
|
||||
elseif bufwinnr(s:buf_nr) != bufwinnr('%')
|
||||
execute bufwinnr(s:buf_nr) . 'wincmd w'
|
||||
endif
|
||||
|
||||
setlocal filetype=godoc
|
||||
setlocal bufhidden=delete
|
||||
setlocal buftype=nofile
|
||||
setlocal noswapfile
|
||||
setlocal nobuflisted
|
||||
setlocal nocursorline
|
||||
setlocal nocursorcolumn
|
||||
setlocal iskeyword+=:
|
||||
setlocal iskeyword-=-
|
||||
|
||||
setlocal modifiable
|
||||
%delete _
|
||||
call append(0, split(a:content, "\n"))
|
||||
sil $delete _
|
||||
setlocal nomodifiable
|
||||
endfunction
|
||||
|
||||
|
||||
" vim:ts=4:sw=4:et
|
@ -0,0 +1,42 @@
|
||||
if !exists("g:go_errcheck_bin")
|
||||
let g:go_errcheck_bin = "errcheck"
|
||||
endif
|
||||
|
||||
function! go#errcheck#Run(...) abort
|
||||
if a:0 == 0
|
||||
let package = go#package#ImportPath(expand('%:p:h'))
|
||||
else
|
||||
let package = a:1
|
||||
end
|
||||
|
||||
let bin_path = go#tool#BinPath(g:go_errcheck_bin)
|
||||
if empty(bin_path)
|
||||
return
|
||||
endif
|
||||
|
||||
let out = system(bin_path . ' ' . package)
|
||||
if v:shell_error
|
||||
let errors = []
|
||||
let mx = '^\(.\{-}\):\(\d\+\):\(\d\+\)\s*\(.*\)'
|
||||
for line in split(out, '\n')
|
||||
let tokens = matchlist(line, mx)
|
||||
|
||||
if !empty(tokens)
|
||||
call add(errors, {"filename": expand(DefaultGoPath() . "/src/" . tokens[1]),
|
||||
\"lnum": tokens[2],
|
||||
\"col": tokens[3],
|
||||
\"text": tokens[4]})
|
||||
endif
|
||||
endfor
|
||||
if empty(errors)
|
||||
% | " Couldn't detect error format, output errors
|
||||
endif
|
||||
if !empty(errors)
|
||||
call setqflist(errors, 'r')
|
||||
endif
|
||||
echohl Error | echomsg "GoErrCheck returned error" | echohl None
|
||||
else
|
||||
call setqflist([])
|
||||
endif
|
||||
cwindow
|
||||
endfunction
|
@ -0,0 +1,141 @@
|
||||
" Copyright 2011 The Go Authors. All rights reserved.
|
||||
" Use of this source code is governed by a BSD-style
|
||||
" license that can be found in the LICENSE file.
|
||||
"
|
||||
" fmt.vim: Vim command to format Go files with gofmt.
|
||||
"
|
||||
" This filetype plugin add a new commands for go buffers:
|
||||
"
|
||||
" :Fmt
|
||||
"
|
||||
" Filter the current Go buffer through gofmt.
|
||||
" It tries to preserve cursor position and avoids
|
||||
" replacing the buffer with stderr output.
|
||||
"
|
||||
" Options:
|
||||
"
|
||||
" g:go_fmt_command [default="gofmt"]
|
||||
"
|
||||
" Flag naming the gofmt executable to use.
|
||||
"
|
||||
" g:go_fmt_autosave [default=1]
|
||||
"
|
||||
" Flag to auto call :Fmt when saved file
|
||||
"
|
||||
|
||||
if !exists("g:go_fmt_command")
|
||||
let g:go_fmt_command = "gofmt"
|
||||
endif
|
||||
|
||||
if !exists("g:go_goimports_bin")
|
||||
let g:go_goimports_bin = "goimports"
|
||||
endif
|
||||
|
||||
if !exists('g:go_fmt_fail_silently')
|
||||
let g:go_fmt_fail_silently = 0
|
||||
endif
|
||||
|
||||
if !exists('g:go_fmt_options')
|
||||
let g:go_fmt_options = ''
|
||||
endif
|
||||
|
||||
let s:got_fmt_error = 0
|
||||
|
||||
" we have those problems :
|
||||
" http://stackoverflow.com/questions/12741977/prevent-vim-from-updating-its-undo-tree
|
||||
" http://stackoverflow.com/questions/18532692/golang-formatter-and-vim-how-to-destroy-history-record?rq=1
|
||||
"
|
||||
" The below function is an improved version that aims to fix all problems.
|
||||
" it doesn't undo changes and break undo history. If you are here reading
|
||||
" this and have VimL experience, please look at the function for
|
||||
" improvements, patches are welcome :)
|
||||
function! go#fmt#Format(withGoimport)
|
||||
" save cursor position and many other things
|
||||
let l:curw=winsaveview()
|
||||
|
||||
" needed for testing if gofmt fails or not
|
||||
let l:tmpname=tempname()
|
||||
call writefile(getline(1,'$'), l:tmpname)
|
||||
|
||||
" save our undo file to be restored after we are done. This is needed to
|
||||
" 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()
|
||||
exe 'wundo! ' . tmpundofile
|
||||
|
||||
" get the command first so we can test it
|
||||
let fmt_command = g:go_fmt_command
|
||||
if a:withGoimport == 1
|
||||
" check if the user has installed goimports
|
||||
let bin_path = go#tool#BinPath(g:go_goimports_bin)
|
||||
if empty(bin_path)
|
||||
return
|
||||
endif
|
||||
|
||||
let fmt_command = bin_path
|
||||
endif
|
||||
|
||||
" populate the final command with user based fmt options
|
||||
let command = fmt_command . ' ' . g:go_fmt_options
|
||||
|
||||
" execute our command...
|
||||
let out = system(command . " " . l:tmpname)
|
||||
|
||||
"if there is no error on the temp file, gofmt again our original file
|
||||
if v:shell_error == 0
|
||||
" remove undo point caused via BufWritePre
|
||||
try | silent undojoin | catch | endtry
|
||||
|
||||
" do not include stderr to the buffer, this is due to goimports/gofmt
|
||||
" tha fails with a zero exit return value (sad yeah).
|
||||
let default_srr = &srr
|
||||
set srr=>%s
|
||||
|
||||
" execufe gofmt on the current buffer and replace it
|
||||
silent execute "%!" . command
|
||||
|
||||
" only clear quickfix if it was previously set, this prevents closing
|
||||
" other quickfixes
|
||||
if s:got_fmt_error
|
||||
let s:got_fmt_error = 0
|
||||
call setqflist([])
|
||||
cwindow
|
||||
endif
|
||||
|
||||
" put back the users srr setting
|
||||
let &srr = default_srr
|
||||
elseif g:go_fmt_fail_silently == 0
|
||||
"otherwise get the errors and put them to quickfix window
|
||||
let errors = []
|
||||
for line in split(out, '\n')
|
||||
let tokens = matchlist(line, '^\(.\{-}\):\(\d\+\):\(\d\+\)\s*\(.*\)')
|
||||
if !empty(tokens)
|
||||
call add(errors, {"filename": @%,
|
||||
\"lnum": tokens[2],
|
||||
\"col": tokens[3],
|
||||
\"text": tokens[4]})
|
||||
endif
|
||||
endfor
|
||||
if empty(errors)
|
||||
% | " Couldn't detect gofmt error format, output errors
|
||||
endif
|
||||
if !empty(errors)
|
||||
call setqflist(errors, 'r')
|
||||
echohl Error | echomsg "Gofmt returned error" | echohl None
|
||||
endif
|
||||
let s:got_fmt_error = 1
|
||||
cwindow
|
||||
endif
|
||||
|
||||
" restore our undo history
|
||||
silent! exe 'rundo ' . tmpundofile
|
||||
call delete(tmpundofile)
|
||||
|
||||
" restore our cursor/windows positions
|
||||
call delete(l:tmpname)
|
||||
call winrestview(l:curw)
|
||||
endfunction
|
||||
|
||||
|
||||
" vim:ts=4:sw=4:et
|
@ -0,0 +1,236 @@
|
||||
" Copyright 2011 The Go Authors. All rights reserved.
|
||||
" Use of this source code is governed by a BSD-style
|
||||
" license that can be found in the LICENSE file.
|
||||
"
|
||||
" import.vim: Vim commands to import/drop Go packages.
|
||||
"
|
||||
" This filetype plugin adds three new commands for go buffers:
|
||||
"
|
||||
" :GoImport {path}
|
||||
"
|
||||
" Import ensures that the provided package {path} is imported
|
||||
" in the current Go buffer, using proper style and ordering.
|
||||
" If {path} is already being imported, an error will be
|
||||
" displayed and the buffer will be untouched.
|
||||
"
|
||||
" :GoImportAs {localname} {path}
|
||||
"
|
||||
" Same as Import, but uses a custom local name for the package.
|
||||
"
|
||||
" :GoDrop {path}
|
||||
"
|
||||
" Remove the import line for the provided package {path}, if
|
||||
" present in the current Go buffer. If {path} is not being
|
||||
" imported, an error will be displayed and the buffer will be
|
||||
" untouched.
|
||||
"
|
||||
" If you would like to add shortcuts, you can do so by doing the following:
|
||||
"
|
||||
" Import fmt
|
||||
" au Filetype go nnoremap <buffer> <LocalLeader>f :Import fmt<CR>
|
||||
"
|
||||
" Drop fmt
|
||||
" au Filetype go nnoremap <buffer> <LocalLeader>F :Drop fmt<CR>
|
||||
"
|
||||
" Import the word under your cursor
|
||||
" au Filetype go nnoremap <buffer> <LocalLeader>k
|
||||
" \ :exe 'Import ' . expand('<cword>')<CR>
|
||||
"
|
||||
" The backslash '\' is the default maplocalleader, so it is possible that
|
||||
" your vim is set to use a different character (:help maplocalleader).
|
||||
"
|
||||
function! go#import#SwitchImport(enabled, localname, path)
|
||||
let view = winsaveview()
|
||||
let path = a:path
|
||||
|
||||
" Quotes are not necessary, so remove them if provided.
|
||||
if path[0] == '"'
|
||||
let path = strpart(path, 1)
|
||||
endif
|
||||
if path[len(path)-1] == '"'
|
||||
let path = strpart(path, 0, len(path) - 1)
|
||||
endif
|
||||
if path == ''
|
||||
call s:Error('Import path not provided')
|
||||
return
|
||||
endif
|
||||
|
||||
let exists = go#tool#Exists(path)
|
||||
if exists == -1
|
||||
call s:Error("Can't find import: " . path)
|
||||
return
|
||||
endif
|
||||
|
||||
" Extract any site prefix (e.g. github.com/).
|
||||
" If other imports with the same prefix are grouped separately,
|
||||
" we will add this new import with them.
|
||||
" Only up to and including the first slash is used.
|
||||
let siteprefix = matchstr(path, "^[^/]*/")
|
||||
|
||||
let qpath = '"' . path . '"'
|
||||
if a:localname != ''
|
||||
let qlocalpath = a:localname . ' ' . qpath
|
||||
else
|
||||
let qlocalpath = qpath
|
||||
endif
|
||||
let indentstr = 0
|
||||
let packageline = -1 " Position of package name statement
|
||||
let appendline = -1 " Position to introduce new import
|
||||
let deleteline = -1 " Position of line with existing import
|
||||
let linesdelta = 0 " Lines added/removed
|
||||
|
||||
" Find proper place to add/remove import.
|
||||
let line = 0
|
||||
while line <= line('$')
|
||||
let linestr = getline(line)
|
||||
|
||||
if linestr =~# '^package\s'
|
||||
let packageline = line
|
||||
let appendline = line
|
||||
|
||||
elseif linestr =~# '^import\s\+('
|
||||
let appendstr = qlocalpath
|
||||
let indentstr = 1
|
||||
let appendline = line
|
||||
let firstblank = -1
|
||||
let lastprefix = ""
|
||||
while line <= line("$")
|
||||
let line = line + 1
|
||||
let linestr = getline(line)
|
||||
let m = matchlist(getline(line), '^\()\|\(\s\+\)\(\S*\s*\)"\(.\+\)"\)')
|
||||
if empty(m)
|
||||
if siteprefix == "" && a:enabled
|
||||
" must be in the first group
|
||||
break
|
||||
endif
|
||||
" record this position, but keep looking
|
||||
if firstblank < 0
|
||||
let firstblank = line
|
||||
endif
|
||||
continue
|
||||
endif
|
||||
if m[1] == ')'
|
||||
" if there's no match, add it to the first group
|
||||
if appendline < 0 && firstblank >= 0
|
||||
let appendline = firstblank
|
||||
endif
|
||||
break
|
||||
endif
|
||||
let lastprefix = matchstr(m[4], "^[^/]*/")
|
||||
if a:localname != '' && m[3] != ''
|
||||
let qlocalpath = printf('%-' . (len(m[3])-1) . 's %s', a:localname, qpath)
|
||||
endif
|
||||
let appendstr = m[2] . qlocalpath
|
||||
let indentstr = 0
|
||||
if m[4] == path
|
||||
let appendline = -1
|
||||
let deleteline = line
|
||||
break
|
||||
elseif m[4] < path
|
||||
" don't set candidate position if we have a site prefix,
|
||||
" we've passed a blank line, and this doesn't share the same
|
||||
" site prefix.
|
||||
if siteprefix == "" || firstblank < 0 || match(m[4], "^" . siteprefix) >= 0
|
||||
let appendline = line
|
||||
endif
|
||||
elseif siteprefix != "" && match(m[4], "^" . siteprefix) >= 0
|
||||
" first entry of site group
|
||||
let appendline = line - 1
|
||||
break
|
||||
endif
|
||||
endwhile
|
||||
break
|
||||
|
||||
elseif linestr =~# '^import '
|
||||
if appendline == packageline
|
||||
let appendstr = 'import ' . qlocalpath
|
||||
let appendline = line - 1
|
||||
endif
|
||||
let m = matchlist(linestr, '^import\(\s\+\)\(\S*\s*\)"\(.\+\)"')
|
||||
if !empty(m)
|
||||
if m[3] == path
|
||||
let appendline = -1
|
||||
let deleteline = line
|
||||
break
|
||||
endif
|
||||
if m[3] < path
|
||||
let appendline = line
|
||||
endif
|
||||
if a:localname != '' && m[2] != ''
|
||||
let qlocalpath = printf("%s %" . len(m[2])-1 . "s", a:localname, qpath)
|
||||
endif
|
||||
let appendstr = 'import' . m[1] . qlocalpath
|
||||
endif
|
||||
|
||||
elseif linestr =~# '^\(var\|const\|type\|func\)\>'
|
||||
break
|
||||
|
||||
endif
|
||||
let line = line + 1
|
||||
endwhile
|
||||
|
||||
" Append or remove the package import, as requested.
|
||||
if a:enabled
|
||||
if deleteline != -1
|
||||
call s:Error(qpath . ' already being imported')
|
||||
elseif appendline == -1
|
||||
call s:Error('No package line found')
|
||||
else
|
||||
if appendline == packageline
|
||||
call append(appendline + 0, '')
|
||||
call append(appendline + 1, 'import (')
|
||||
call append(appendline + 2, ')')
|
||||
let appendline += 2
|
||||
let linesdelta += 3
|
||||
let appendstr = qlocalpath
|
||||
let indentstr = 1
|
||||
endif
|
||||
call append(appendline, appendstr)
|
||||
execute appendline + 1
|
||||
if indentstr
|
||||
execute 'normal >>'
|
||||
endif
|
||||
let linesdelta += 1
|
||||
endif
|
||||
else
|
||||
if deleteline == -1
|
||||
call s:Error(qpath . ' not being imported')
|
||||
else
|
||||
execute deleteline . 'd'
|
||||
let linesdelta -= 1
|
||||
|
||||
if getline(deleteline-1) =~# '^import\s\+(' && getline(deleteline) =~# '^)'
|
||||
" Delete empty import block
|
||||
let deleteline -= 1
|
||||
execute deleteline . "d"
|
||||
execute deleteline . "d"
|
||||
let linesdelta -= 2
|
||||
endif
|
||||
|
||||
if getline(deleteline) == '' && getline(deleteline - 1) == ''
|
||||
" Delete spacing for removed line too.
|
||||
execute deleteline . "d"
|
||||
let linesdelta -= 1
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
" Adjust view for any changes.
|
||||
let view.lnum += linesdelta
|
||||
let view.topline += linesdelta
|
||||
if view.topline < 0
|
||||
let view.topline = 0
|
||||
endif
|
||||
|
||||
" Put buffer back where it was.
|
||||
call winrestview(view)
|
||||
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:Error(s)
|
||||
echohl Error | echo a:s | echohl None
|
||||
endfunction
|
||||
|
||||
|
||||
" vim:ts=4:sw=4:et
|
@ -0,0 +1,30 @@
|
||||
" Copyright 2013 The Go Authors. All rights reserved.
|
||||
" Use of this source code is governed by a BSD-style
|
||||
" license that can be found in the LICENSE file.
|
||||
"
|
||||
" lint.vim: Vim command to lint Go files with golint.
|
||||
"
|
||||
" https://github.com/golang/lint
|
||||
"
|
||||
" This filetype plugin add a new commands for go buffers:
|
||||
"
|
||||
" :GoLint
|
||||
"
|
||||
" Run golint for the current Go file.
|
||||
"
|
||||
if !exists("g:go_golint_bin")
|
||||
let g:go_golint_bin = "golint"
|
||||
endif
|
||||
|
||||
function! go#lint#Run() abort
|
||||
let bin_path = go#tool#BinPath(g:go_golint_bin)
|
||||
if empty(bin_path)
|
||||
return
|
||||
endif
|
||||
|
||||
silent cexpr system(bin_path . " " . shellescape(expand('%')))
|
||||
cwindow
|
||||
endfunction
|
||||
|
||||
|
||||
" vim:ts=4:sw=4:et
|
@ -0,0 +1,224 @@
|
||||
" -*- text -*-
|
||||
" 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
|
||||
|
||||
func! s:qflist(output)
|
||||
let qflist = []
|
||||
" 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(qflist, item)
|
||||
endfor
|
||||
call setqflist(qflist)
|
||||
cwindow
|
||||
endfun
|
||||
|
||||
func! s:getpos(l, c)
|
||||
if &encoding != 'utf-8'
|
||||
let buf = a:l == 1 ? '' : (join(getline(1, a:l-1), "\n") . "\n")
|
||||
let buf .= a:c == 1 ? '' : getline('.')[:a:c-2]
|
||||
return len(iconv(buf, &encoding, 'utf-8'))
|
||||
endif
|
||||
return line2byte(a:l) + (a:c-2)
|
||||
endfun
|
||||
|
||||
func! s:RunOracle(mode, selected) range abort
|
||||
let fname = expand('%:p')
|
||||
let dname = expand('%:p:h')
|
||||
let pkg = go#package#ImportPath(dname)
|
||||
|
||||
if exists('g:go_oracle_scope_file')
|
||||
" let the user defines the scope
|
||||
let sname = shellescape(get(g:, 'go_oracle_scope_file'))
|
||||
elseif exists('g:go_oracle_include_tests') && pkg != -1
|
||||
" give import path so it includes all _test.go files too
|
||||
let sname = shellescape(pkg)
|
||||
else
|
||||
" best usable way, only pass the package itself, without the test
|
||||
" files
|
||||
let sname = join(go#tool#Files(), ' ')
|
||||
endif
|
||||
|
||||
"return with a warning if the bin doesn't exist
|
||||
let bin_path = go#tool#BinPath(g:go_oracle_bin)
|
||||
if empty(bin_path)
|
||||
return
|
||||
endif
|
||||
|
||||
if a:selected != -1
|
||||
let pos1 = s:getpos(line("'<"), col("'<"))
|
||||
let pos2 = s:getpos(line("'>"), col("'>"))
|
||||
let cmd = printf('%s -format json -pos=%s:#%d,#%d %s %s',
|
||||
\ bin_path,
|
||||
\ shellescape(fname), pos1, pos2, a:mode, sname)
|
||||
else
|
||||
let pos = s:getpos(line('.'), col('.'))
|
||||
let cmd = printf('%s -format json -pos=%s:#%d %s %s',
|
||||
\ bin_path,
|
||||
\ shellescape(fname), pos, a:mode, sname)
|
||||
endif
|
||||
|
||||
echon "vim-go: " | echohl Identifier | echon "analysing ..." | echohl None
|
||||
|
||||
let out = system(cmd)
|
||||
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.
|
||||
" echo out
|
||||
" redraw | echon 'vim-go: could not run static analyser (does it build?)'
|
||||
redraw | echon "vim-go: " | echohl Statement | echon out | echohl None
|
||||
return {}
|
||||
else
|
||||
let json_decoded = webapi#json#decode(out)
|
||||
return json_decoded
|
||||
endif
|
||||
endfun
|
||||
|
||||
|
||||
" Show 'implements' relation for selected package
|
||||
function! go#oracle#Implements(selected)
|
||||
let out = s:RunOracle('implements', a:selected)
|
||||
if empty(out)
|
||||
return
|
||||
endif
|
||||
|
||||
" be sure they exists before we retrieve them from the map
|
||||
if !has_key(out, "implements")
|
||||
return
|
||||
endif
|
||||
|
||||
if has_key(out.implements, "from")
|
||||
let interfaces = out.implements.from
|
||||
elseif has_key(out.implements, "fromptr")
|
||||
let interfaces = out.implements.fromptr
|
||||
else
|
||||
redraw | echon "vim-go: " | echon "does not satisfy any interface"| echohl None
|
||||
return
|
||||
endif
|
||||
|
||||
" get the type name from the type under the cursor
|
||||
let typeName = out.implements.type.name
|
||||
|
||||
" prepare the title
|
||||
let title = typeName . " implements:"
|
||||
|
||||
" start to populate our buffer content
|
||||
let result = [title, ""]
|
||||
|
||||
for interface in interfaces
|
||||
" don't add runtime interfaces
|
||||
if interface.name !~ '^runtime'
|
||||
let line = interface.name . "\t" . interface.pos
|
||||
call add(result, line)
|
||||
endif
|
||||
endfor
|
||||
|
||||
" open a window and put the result
|
||||
call go#ui#OpenWindow(result)
|
||||
|
||||
" define some buffer related mappings:
|
||||
"
|
||||
" go to definition when hit enter
|
||||
nnoremap <buffer> <CR> :<C-u>call go#ui#OpenDefinition()<CR>
|
||||
" close the window when hit ctrl-c
|
||||
nnoremap <buffer> <c-c> :<C-u>call go#ui#CloseWindow()<CR>
|
||||
endfunction
|
||||
|
||||
" Describe selected syntax: definition, methods, etc
|
||||
function! go#oracle#Describe(selected)
|
||||
let out = s:RunOracle('describe', a:selected)
|
||||
if empty(out)
|
||||
return
|
||||
endif
|
||||
|
||||
echo out
|
||||
return
|
||||
|
||||
let detail = out["describe"]["detail"]
|
||||
let desc = out["describe"]["desc"]
|
||||
|
||||
echo '# detail: '. detail
|
||||
" package, constant, variable, type, function or statement labe
|
||||
if detail == "package"
|
||||
echo desc
|
||||
return
|
||||
endif
|
||||
|
||||
if detail == "value"
|
||||
echo desc
|
||||
echo out["describe"]["value"]
|
||||
return
|
||||
endif
|
||||
|
||||
" the rest needs to be implemented
|
||||
echo desc
|
||||
endfunction
|
||||
|
||||
" Show possible targets of selected function call
|
||||
function! go#oracle#Callees(selected)
|
||||
let out = s:RunOracle('callees', a:selected)
|
||||
echo out
|
||||
endfunction
|
||||
|
||||
" Show possible callers of selected function
|
||||
function! go#oracle#Callers(selected)
|
||||
let out = s:RunOracle('callers', a:selected)
|
||||
echo out
|
||||
endfunction
|
||||
|
||||
" Show the callgraph of the current program.
|
||||
function! go#oracle#Callgraph(selected)
|
||||
let out = s:RunOracle('callgraph', a:selected)
|
||||
echo out
|
||||
endfunction
|
||||
|
||||
" Show path from callgraph root to selected function
|
||||
function! go#oracle#Callstack(selected)
|
||||
let out = s:RunOracle('callstack', a:selected)
|
||||
echo out
|
||||
endfunction
|
||||
|
||||
" Show free variables of selection
|
||||
function! go#oracle#Freevars(selected)
|
||||
let out = s:RunOracle('freevars', a:selected)
|
||||
echo out
|
||||
endfunction
|
||||
|
||||
" Show send/receive corresponding to selected channel op
|
||||
function! go#oracle#Peers(selected)
|
||||
let out = s:RunOracle('peers', a:selected)
|
||||
echo out
|
||||
endfunction
|
||||
|
||||
" Show all refs to entity denoted by selected identifier
|
||||
function! go#oracle#Referrers(selected)
|
||||
let out = s:RunOracle('referrers', a:selected)
|
||||
echo out
|
||||
endfunction
|
||||
|
||||
" vim:ts=4:sw=4:et
|
@ -0,0 +1,152 @@
|
||||
" Copyright 2011 The Go Authors. All rights reserved.
|
||||
" Use of this source code is governed by a BSD-style
|
||||
" license that can be found in the LICENSE file.
|
||||
"
|
||||
" This file provides a utility function that performs auto-completion of
|
||||
" package names, for use by other commands.
|
||||
|
||||
let s:goos = $GOOS
|
||||
let s:goarch = $GOARCH
|
||||
|
||||
if len(s:goos) == 0
|
||||
if exists('g:golang_goos')
|
||||
let s:goos = g:golang_goos
|
||||
elseif has('win32') || has('win64')
|
||||
let s:goos = 'windows'
|
||||
elseif has('macunix')
|
||||
let s:goos = 'darwin'
|
||||
else
|
||||
let s:goos = '*'
|
||||
endif
|
||||
endif
|
||||
|
||||
if len(s:goarch) == 0
|
||||
if exists('g:golang_goarch')
|
||||
let s:goarch = g:golang_goarch
|
||||
else
|
||||
let s:goarch = '*'
|
||||
endif
|
||||
endif
|
||||
|
||||
function! go#package#Paths()
|
||||
let dirs = []
|
||||
|
||||
if executable('go')
|
||||
let goroot = substitute(system('go env GOROOT'), '\n', '', 'g')
|
||||
if v:shell_error
|
||||
echomsg '''go env GOROOT'' failed'
|
||||
endif
|
||||
else
|
||||
let goroot = $GOROOT
|
||||
endif
|
||||
|
||||
if len(goroot) != 0 && isdirectory(goroot)
|
||||
let dirs += [goroot]
|
||||
endif
|
||||
|
||||
let pathsep = ':'
|
||||
if s:goos == 'windows'
|
||||
let pathsep = ';'
|
||||
endif
|
||||
let workspaces = split($GOPATH, pathsep)
|
||||
if workspaces != []
|
||||
let dirs += workspaces
|
||||
endif
|
||||
|
||||
return dirs
|
||||
endfunction
|
||||
|
||||
function! go#package#ImportPath(arg)
|
||||
let path = fnamemodify(resolve(a:arg), ':p')
|
||||
let dirs = go#package#Paths()
|
||||
|
||||
for dir in dirs
|
||||
if len(dir) && match(path, dir) == 0
|
||||
let workspace = dir
|
||||
endif
|
||||
endfor
|
||||
|
||||
if !exists('workspace')
|
||||
return -1
|
||||
endif
|
||||
|
||||
return substitute(path, workspace . '/src/', '', '')
|
||||
endfunction
|
||||
|
||||
function! go#package#FromPath(arg)
|
||||
let path = fnamemodify(resolve(a:arg), ':p')
|
||||
let dirs = go#package#Paths()
|
||||
|
||||
for dir in dirs
|
||||
if len(dir) && match(path, dir) == 0
|
||||
let workspace = dir
|
||||
endif
|
||||
endfor
|
||||
|
||||
if !exists('workspace')
|
||||
return -1
|
||||
endif
|
||||
|
||||
if isdirectory(path)
|
||||
return substitute(path, workspace . 'src/', '', '')
|
||||
else
|
||||
return substitute(substitute(path, workspace . 'src/', '', ''),
|
||||
\ '/' . fnamemodify(path, ':t'), '', '')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! go#package#CompleteMembers(package, member)
|
||||
silent! let content = system('godoc ' . a:package)
|
||||
if v:shell_error || !len(content)
|
||||
return []
|
||||
endif
|
||||
let lines = filter(split(content, "\n"),"v:val !~ '^\\s\\+$'")
|
||||
try
|
||||
let mx1 = '^\s\+\(\S+\)\s\+=\s\+.*'
|
||||
let mx2 = '^\%(const\|var\|type\|func\) \([A-Z][^ (]\+\).*'
|
||||
let candidates = map(filter(copy(lines), 'v:val =~ mx1'),
|
||||
\ 'substitute(v:val, mx1, "\\1", "")')
|
||||
\ + map(filter(copy(lines), 'v:val =~ mx2'),
|
||||
\ 'substitute(v:val, mx2, "\\1", "")')
|
||||
return filter(candidates, '!stridx(v:val, a:member)')
|
||||
catch
|
||||
return []
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! go#package#Complete(ArgLead, CmdLine, CursorPos)
|
||||
let words = split(a:CmdLine, '\s\+', 1)
|
||||
if len(words) > 2 && words[0] != "GoImportAs"
|
||||
" Complete package members
|
||||
return go#package#CompleteMembers(words[1], words[2])
|
||||
endif
|
||||
|
||||
let dirs = go#package#Paths()
|
||||
|
||||
if len(dirs) == 0
|
||||
" should not happen
|
||||
return []
|
||||
endif
|
||||
|
||||
let ret = {}
|
||||
for dir in dirs
|
||||
" this may expand to multiple lines
|
||||
let root = split(expand(dir . '/pkg/' . s:goos . '_' . s:goarch), "\n")
|
||||
call add(root, expand(dir . '/src'))
|
||||
for r in root
|
||||
for i in split(globpath(r, a:ArgLead.'*'), "\n")
|
||||
if isdirectory(i)
|
||||
let i .= '/'
|
||||
elseif i !~ '\.a$'
|
||||
continue
|
||||
endif
|
||||
let i = substitute(substitute(i[len(r)+1:], '[\\]', '/', 'g'),
|
||||
\ '\.a$', '', 'g')
|
||||
let ret[i] = i
|
||||
endfor
|
||||
endfor
|
||||
endfor
|
||||
return sort(keys(ret))
|
||||
endfunction
|
||||
|
||||
" vim:sw=4:et
|
@ -0,0 +1,94 @@
|
||||
if !exists("g:go_play_open_browser")
|
||||
let g:go_play_open_browser = 1
|
||||
endif
|
||||
|
||||
|
||||
function! go#play#Share(count, line1, line2)
|
||||
if !executable('curl')
|
||||
echohl ErrorMsg | echomsg "vim-go: require 'curl' command" | echohl None
|
||||
return
|
||||
endif
|
||||
|
||||
let content = join(getline(a:line1, a:line2), "\n")
|
||||
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)
|
||||
|
||||
" we can remove the temp file because it's now posted.
|
||||
call delete(share_file)
|
||||
|
||||
if v:shell_error
|
||||
echo 'A error has occured. Run this command to see what the problem is:'
|
||||
echo command
|
||||
return
|
||||
endif
|
||||
|
||||
let url = "http://play.golang.org/p/".snippet_id
|
||||
|
||||
" copy to clipboard
|
||||
if has('unix') && !has('xterm_clipboard') && !has('clipboard')
|
||||
let @" = url
|
||||
else
|
||||
let @+ = url
|
||||
endif
|
||||
|
||||
if g:go_play_open_browser != 0
|
||||
call go#tool#OpenBrowser(url)
|
||||
endif
|
||||
|
||||
echo "vim-go: snippet uploaded: ".url
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:get_visual_content()
|
||||
let save_regcont = @"
|
||||
let save_regtype = getregtype('"')
|
||||
silent! normal! gvy
|
||||
let content = @"
|
||||
call setreg('"', save_regcont, save_regtype)
|
||||
return content
|
||||
endfunction
|
||||
|
||||
" modified version of
|
||||
" http://stackoverflow.com/questions/1533565/how-to-get-visually-selected-text-in-vimscript
|
||||
" another function that returns the content of visual selection, it's not used
|
||||
" but might be useful in the future
|
||||
function! s:get_visual_selection()
|
||||
let [lnum1, col1] = getpos("'<")[1:2]
|
||||
let [lnum2, col2] = getpos("'>")[1:2]
|
||||
|
||||
" check if the the visual mode is used before
|
||||
if lnum1 == 0 || lnum2 == 0 || col1 == 0 || col2 == 0
|
||||
return
|
||||
endif
|
||||
|
||||
let lines = getline(lnum1, lnum2)
|
||||
let lines[-1] = lines[-1][: col2 - (&selection == 'inclusive' ? 1 : 2)]
|
||||
let lines[0] = lines[0][col1 - 1:]
|
||||
return join(lines, "\n")
|
||||
endfunction
|
||||
|
||||
" following two functions are from: https://github.com/mattn/gist-vim
|
||||
" thanks @mattn
|
||||
function! s:get_browser_command()
|
||||
let go_play_browser_command = get(g:, 'go_play_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'
|
||||
let go_play_browser_command = 'open %URL%'
|
||||
elseif executable('xdg-open')
|
||||
let go_play_browser_command = 'xdg-open %URL%'
|
||||
elseif executable('firefox')
|
||||
let go_play_browser_command = 'firefox %URL% &'
|
||||
else
|
||||
let go_play_browser_command = ''
|
||||
endif
|
||||
endif
|
||||
return go_play_browser_command
|
||||
endfunction
|
||||
|
||||
|
||||
" vim:ts=4:sw=4:et
|
@ -0,0 +1,52 @@
|
||||
if !exists("g:go_gorename_bin")
|
||||
let g:go_gorename_bin = "gorename"
|
||||
endif
|
||||
|
||||
function! go#rename#Rename(...)
|
||||
let to = ""
|
||||
if a:0 == 0
|
||||
let ask = printf("vim-go: rename '%s' to: ", expand("<cword>"))
|
||||
let to = input(ask)
|
||||
redraw
|
||||
else
|
||||
let to = a:1
|
||||
endif
|
||||
|
||||
|
||||
"return with a warning if the bin doesn't exist
|
||||
let bin_path = go#tool#BinPath(g:go_gorename_bin)
|
||||
if empty(bin_path)
|
||||
return
|
||||
endif
|
||||
|
||||
let fname = expand('%:p:t')
|
||||
let pos = s:getpos(line('.'), col('.'))
|
||||
let cmd = printf('%s -offset %s:#%d -to %s', bin_path, shellescape(fname), pos, to)
|
||||
|
||||
let out = go#tool#ExecuteInDir(cmd)
|
||||
|
||||
" strip out newline on the end that gorename puts. If we don't remove, it
|
||||
" will trigger the 'Hit ENTER to continue' prompt
|
||||
let clean = split(out, '\n')
|
||||
|
||||
if v:shell_error
|
||||
redraw | echon "vim-go: " | echohl Statement | echon clean[0] | echohl None
|
||||
else
|
||||
redraw | echon "vim-go: " | echohl Function | echon clean[0] | echohl None
|
||||
endif
|
||||
|
||||
" refresh the buffer so we can see the new content
|
||||
silent execute ":e"
|
||||
endfunction
|
||||
|
||||
func! s:getpos(l, c)
|
||||
if &encoding != 'utf-8'
|
||||
let buf = a:l == 1 ? '' : (join(getline(1, a:l-1), "\n") . "\n")
|
||||
let buf .= a:c == 1 ? '' : getline('.')[:a:c-2]
|
||||
return len(iconv(buf, &encoding, 'utf-8'))
|
||||
endif
|
||||
return line2byte(a:l) + (a:c-2)
|
||||
endfun
|
||||
|
||||
" vim:ts=4:sw=4:et
|
||||
"
|
@ -0,0 +1,179 @@
|
||||
function! go#tool#Files()
|
||||
if IsWin()
|
||||
let command = 'go list -f "{{range $f := .GoFiles}}{{$.Dir}}\{{$f}}{{printf \"\n\"}}{{end}}"'
|
||||
else
|
||||
" let command = "go list -f $'{{range $f := .GoFiles}}{{$.Dir}}/{{$f}}\n{{end}}'"
|
||||
let command = "go list -f '{{range $f := .GoFiles}}{{$.Dir}}/{{$f}}{{printf \"\\n\"}}{{end}}'"
|
||||
endif
|
||||
let out = go#tool#ExecuteInDir(command)
|
||||
return split(out, '\n')
|
||||
endfunction
|
||||
|
||||
function! go#tool#Deps()
|
||||
if IsWin()
|
||||
let command = 'go list -f "{{range $f := .Deps}}{{$f}}{{printf \"\n\"}}{{end}}"'
|
||||
else
|
||||
let command = "go list -f $'{{range $f := .Deps}}{{$f}}\n{{end}}'"
|
||||
endif
|
||||
let out = go#tool#ExecuteInDir(command)
|
||||
return split(out, '\n')
|
||||
endfunction
|
||||
|
||||
function! go#tool#Imports()
|
||||
let imports = {}
|
||||
if IsWin()
|
||||
let command = 'go list -f "{{range $f := .Imports}}{{$f}}{{printf \"\n\"}}{{end}}"'
|
||||
else
|
||||
let command = "go list -f $'{{range $f := .Imports}}{{$f}}\n{{end}}'"
|
||||
endif
|
||||
let out = go#tool#ExecuteInDir(command)
|
||||
if v:shell_error
|
||||
echo out
|
||||
return imports
|
||||
endif
|
||||
|
||||
for package_path in split(out, '\n')
|
||||
let package_name = fnamemodify(package_path, ":t")
|
||||
let imports[package_name] = package_path
|
||||
endfor
|
||||
|
||||
return imports
|
||||
endfunction
|
||||
|
||||
function! go#tool#ShowErrors(out)
|
||||
let errors = []
|
||||
for line in split(a:out, '\n')
|
||||
let tokens = matchlist(line, '^\s*\(.\{-}\):\(\d\+\):\s*\(.*\)')
|
||||
if !empty(tokens)
|
||||
call add(errors, {"filename" : expand("%:p:h:") . "/" . tokens[1],
|
||||
\"lnum": tokens[2],
|
||||
\"text": tokens[3]})
|
||||
elseif !empty(errors)
|
||||
" Preserve indented lines.
|
||||
" This comes up especially with multi-line test output.
|
||||
if match(line, '^\s') >= 0
|
||||
call add(errors, {"text": line})
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
|
||||
if !empty(errors)
|
||||
call setqflist(errors, 'r')
|
||||
return
|
||||
endif
|
||||
|
||||
if empty(errors)
|
||||
" Couldn't detect error format, output errors
|
||||
echo a:out
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! go#tool#ExecuteInDir(cmd) abort
|
||||
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
|
||||
let dir = getcwd()
|
||||
try
|
||||
execute cd.'`=expand("%:p:h")`'
|
||||
let out = system(a:cmd)
|
||||
finally
|
||||
execute cd.'`=dir`'
|
||||
endtry
|
||||
return out
|
||||
endfunction
|
||||
|
||||
" Exists checks whether the given importpath exists or not. It returns 0 if
|
||||
" the importpath exists under GOPATH.
|
||||
function! go#tool#Exists(importpath)
|
||||
let command = "go list ". a:importpath
|
||||
let out = go#tool#ExecuteInDir(command)
|
||||
|
||||
if v:shell_error
|
||||
return -1
|
||||
endif
|
||||
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
" BinPath checks whether the given binary exists or not and returns the path
|
||||
" of the binary. It returns an empty string doesn't exists.
|
||||
function! go#tool#BinPath(binpath)
|
||||
" remove whitespaces if user applied something like 'goimports '
|
||||
let binpath = substitute(a:binpath, '^\s*\(.\{-}\)\s*$', '\1', '')
|
||||
|
||||
" if it's in PATH just return it
|
||||
if executable(binpath)
|
||||
return binpath
|
||||
endif
|
||||
|
||||
|
||||
" just get the basename
|
||||
let basename = fnamemodify(binpath, ":t")
|
||||
|
||||
" check if we have an appropriate bin_path
|
||||
let go_bin_path = GetBinPath()
|
||||
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_bin_path
|
||||
|
||||
if !executable(binpath)
|
||||
echo "vim-go: could not find '" . basename . "'. Run :GoInstallBinaries to fix it."
|
||||
return ""
|
||||
endif
|
||||
|
||||
" restore back!
|
||||
if go_bin_path
|
||||
let $PATH = old_path
|
||||
endif
|
||||
|
||||
return go_bin_path . '/' . basename
|
||||
endfunction
|
||||
|
||||
" following two functions are from: https://github.com/mattn/gist-vim
|
||||
" thanks @mattn
|
||||
function! s:get_browser_command()
|
||||
let go_play_browser_command = get(g:, 'go_play_browser_command', '')
|
||||
if go_play_browser_command == ''
|
||||
if IsWin()
|
||||
let go_play_browser_command = '!start rundll32 url.dll,FileProtocolHandler %URL%'
|
||||
elseif has('mac') || has('macunix') || has('gui_macvim') || system('uname') =~? '^darwin'
|
||||
let go_play_browser_command = 'open %URL%'
|
||||
elseif executable('xdg-open')
|
||||
let go_play_browser_command = 'xdg-open %URL%'
|
||||
elseif executable('firefox')
|
||||
let go_play_browser_command = 'firefox %URL% &'
|
||||
else
|
||||
let go_play_browser_command = ''
|
||||
endif
|
||||
endif
|
||||
return go_play_browser_command
|
||||
endfunction
|
||||
|
||||
function! go#tool#OpenBrowser(url)
|
||||
let cmd = s:get_browser_command()
|
||||
if len(cmd) == 0
|
||||
redraw
|
||||
echohl WarningMsg
|
||||
echo "It seems that you don't have general web browser. Open URL below."
|
||||
echohl None
|
||||
echo a:url
|
||||
return
|
||||
endif
|
||||
if cmd =~ '^!'
|
||||
let cmd = substitute(cmd, '%URL%', '\=shellescape(a:url)', 'g')
|
||||
silent! exec cmd
|
||||
elseif cmd =~ '^:[A-Z]'
|
||||
let cmd = substitute(cmd, '%URL%', '\=a:url', 'g')
|
||||
exec cmd
|
||||
else
|
||||
let cmd = substitute(cmd, '%URL%', '\=shellescape(a:url)', 'g')
|
||||
call system(cmd)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
" vim:ts=4:sw=4:et
|
@ -0,0 +1,89 @@
|
||||
let s:buf_nr = -1
|
||||
|
||||
"OpenWindow opens a new scratch window and put's the content into the window
|
||||
function! go#ui#OpenWindow(content)
|
||||
" reuse existing buffer window if it exists otherwise create a new one
|
||||
if !bufexists(s:buf_nr)
|
||||
execute 'botright new'
|
||||
file `="[Implements]"`
|
||||
let s:buf_nr = bufnr('%')
|
||||
elseif bufwinnr(s:buf_nr) == -1
|
||||
execute 'botright new'
|
||||
execute s:buf_nr . 'buffer'
|
||||
elseif bufwinnr(s:buf_nr) != bufwinnr('%')
|
||||
execute bufwinnr(s:buf_nr) . 'wincmd w'
|
||||
endif
|
||||
|
||||
|
||||
" Keep minimum height to 10, if there is more just increase it that it
|
||||
" occupies all results
|
||||
let implements_height = 10
|
||||
if len(a:content) < implements_height
|
||||
exe 'resize ' . implements_height
|
||||
else
|
||||
exe 'resize ' . len(a:content)
|
||||
endif
|
||||
|
||||
" some sane default values for a readonly buffer
|
||||
setlocal filetype=vimgo
|
||||
setlocal bufhidden=delete
|
||||
setlocal buftype=nofile
|
||||
setlocal noswapfile
|
||||
setlocal nobuflisted
|
||||
setlocal winfixheight
|
||||
setlocal cursorline " make it easy to distinguish
|
||||
|
||||
" we need this to purge the buffer content
|
||||
setlocal modifiable
|
||||
|
||||
"delete everything first from the buffer
|
||||
%delete _
|
||||
|
||||
" add the content
|
||||
call append(0, a:content)
|
||||
|
||||
" delete last line that comes from the append call
|
||||
$delete _
|
||||
|
||||
" set it back to non modifiable
|
||||
setlocal nomodifiable
|
||||
endfunction
|
||||
|
||||
|
||||
" CloseWindow closes the current window
|
||||
function! go#ui#CloseWindow()
|
||||
close
|
||||
echo ""
|
||||
endfunction
|
||||
|
||||
" OpenDefinition parses the current line and jumps to it by openening a new
|
||||
" tab
|
||||
function! go#ui#OpenDefinition()
|
||||
let curline = getline('.')
|
||||
|
||||
" don't touch our first line and any blank line
|
||||
if curline =~ "implements" || curline =~ "^$"
|
||||
" supress information about calling this function
|
||||
echo ""
|
||||
return
|
||||
endif
|
||||
|
||||
" format: 'interface file:lnum:coln'
|
||||
let mx = '^\(^\S*\)\s*\(.\{-}\):\(\d\+\):\(\d\+\)'
|
||||
|
||||
" parse it now into the list
|
||||
let tokens = matchlist(curline, mx)
|
||||
|
||||
" convert to: 'file:lnum:coln'
|
||||
let expr = tokens[2] . ":" . tokens[3] . ":" . tokens[4]
|
||||
|
||||
" jump to it in a new tab, we use explicit lgetexpr so we can later change
|
||||
" the behaviour via settings (like opening in vsplit instead of tab)
|
||||
lgetexpr expr
|
||||
tab split
|
||||
ll 1
|
||||
|
||||
" center the word
|
||||
norm! zz
|
||||
endfunction
|
||||
|
@ -0,0 +1,135 @@
|
||||
" json
|
||||
" Last Change: 2012-03-08
|
||||
" Maintainer: Yasuhiro Matsumoto <mattn.jp@gmail.com>
|
||||
" License: This file is placed in the public domain.
|
||||
" Reference:
|
||||
"
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
function! webapi#json#null()
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
function! webapi#json#true()
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
function! webapi#json#false()
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
function! s:nr2byte(nr)
|
||||
if a:nr < 0x80
|
||||
return nr2char(a:nr)
|
||||
elseif a:nr < 0x800
|
||||
return nr2char(a:nr/64+192).nr2char(a:nr%64+128)
|
||||
else
|
||||
return nr2char(a:nr/4096%16+224).nr2char(a:nr/64%64+128).nr2char(a:nr%64+128)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:nr2enc_char(charcode)
|
||||
if &encoding == 'utf-8'
|
||||
return nr2char(a:charcode)
|
||||
endif
|
||||
let char = s:nr2byte(a:charcode)
|
||||
if strlen(char) > 1
|
||||
let char = strtrans(iconv(char, 'utf-8', &encoding))
|
||||
endif
|
||||
return char
|
||||
endfunction
|
||||
|
||||
function! s:fixup(val, tmp)
|
||||
if type(a:val) == 0
|
||||
return a:val
|
||||
elseif type(a:val) == 1
|
||||
if a:val == a:tmp.'null'
|
||||
return function('webapi#json#null')
|
||||
elseif a:val == a:tmp.'true'
|
||||
return function('webapi#json#true')
|
||||
elseif a:val == a:tmp.'false'
|
||||
return function('webapi#json#false')
|
||||
endif
|
||||
return a:val
|
||||
elseif type(a:val) == 2
|
||||
return a:val
|
||||
elseif type(a:val) == 3
|
||||
return map(a:val, 's:fixup(v:val, a:tmp)')
|
||||
elseif type(a:val) == 4
|
||||
return map(a:val, 's:fixup(v:val, a:tmp)')
|
||||
else
|
||||
return string(a:val)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! webapi#json#decode(json)
|
||||
let json = iconv(a:json, "utf-8", &encoding)
|
||||
if get(g:, 'webapi#json#parse_strict', 1) == 1 && substitute(substitute(substitute(
|
||||
\ json,
|
||||
\ '\\\%(["\\/bfnrt]\|u[0-9a-fA-F]\{4}\)', '\@', 'g'),
|
||||
\ '"[^\"\\\n\r]*\"\|true\|false\|null\|-\?\d\+'
|
||||
\ . '\%(\.\d*\)\?\%([eE][+\-]\{-}\d\+\)\?', ']', 'g'),
|
||||
\ '\%(^\|:\|,\)\%(\s*\[\)\+', '', 'g') !~ '^[\],:{} \t\n]*$'
|
||||
throw json
|
||||
endif
|
||||
let json = substitute(json, '\n', '', 'g')
|
||||
let json = substitute(json, '\\u34;', '\\"', 'g')
|
||||
if v:version >= 703 && has('patch780')
|
||||
let json = substitute(json, '\\u\(\x\x\x\x\)', '\=iconv(nr2char(str2nr(submatch(1), 16), 1), "utf-8", &encoding)', 'g')
|
||||
else
|
||||
let json = substitute(json, '\\u\(\x\x\x\x\)', '\=s:nr2enc_char("0x".submatch(1))', 'g')
|
||||
endif
|
||||
if get(g:, 'webapi#json#allow_nil', 0) != 0
|
||||
let tmp = '__WEBAPI_JSON__'
|
||||
while 1
|
||||
if stridx(json, tmp) == -1
|
||||
break
|
||||
endif
|
||||
let tmp .= '_'
|
||||
endwhile
|
||||
let [null,true,false] = [
|
||||
\ tmp.'null',
|
||||
\ tmp.'true',
|
||||
\ tmp.'false']
|
||||
sandbox let ret = eval(json)
|
||||
call s:fixup(ret, tmp)
|
||||
else
|
||||
let [null,true,false] = [0,1,0]
|
||||
sandbox let ret = eval(json)
|
||||
endif
|
||||
return ret
|
||||
endfunction
|
||||
|
||||
function! webapi#json#encode(val)
|
||||
if type(a:val) == 0
|
||||
return a:val
|
||||
elseif type(a:val) == 1
|
||||
let json = '"' . escape(a:val, '\"') . '"'
|
||||
let json = substitute(json, "\r", '\\r', 'g')
|
||||
let json = substitute(json, "\n", '\\n', 'g')
|
||||
let json = substitute(json, "\t", '\\t', 'g')
|
||||
let json = substitute(json, '\([[:cntrl:]]\)', '\=printf("\x%02d", char2nr(submatch(1)))', 'g')
|
||||
return iconv(json, &encoding, "utf-8")
|
||||
elseif type(a:val) == 2
|
||||
let s = string(a:val)
|
||||
if s == "function('webapi#json#null')"
|
||||
return 'null'
|
||||
elseif s == "function('webapi#json#true')"
|
||||
return 'true'
|
||||
elseif s == "function('webapi#json#false')"
|
||||
return 'false'
|
||||
endif
|
||||
elseif type(a:val) == 3
|
||||
return '[' . join(map(copy(a:val), 'webapi#json#encode(v:val)'), ',') . ']'
|
||||
elseif type(a:val) == 4
|
||||
return '{' . join(map(keys(a:val), 'webapi#json#encode(v:val).":".webapi#json#encode(a:val[v:val])'), ',') . '}'
|
||||
else
|
||||
return string(a:val)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
||||
|
||||
" vim:set et:
|
@ -0,0 +1,31 @@
|
||||
" Copyright 2013 The Go Authors. All rights reserved.
|
||||
" Use of this source code is governed by a BSD-style
|
||||
" license that can be found in the LICENSE file.
|
||||
"
|
||||
" compiler/go.vim: Vim compiler file for Go.
|
||||
|
||||
if exists("current_compiler")
|
||||
finish
|
||||
endif
|
||||
let current_compiler = "go"
|
||||
|
||||
if exists(":CompilerSet") != 2
|
||||
command -nargs=* CompilerSet setlocal <args>
|
||||
endif
|
||||
|
||||
let s:save_cpo = &cpo
|
||||
set cpo-=C
|
||||
|
||||
CompilerSet makeprg=go\ build
|
||||
CompilerSet errorformat=
|
||||
\%-G#\ %.%#,
|
||||
\%-G%.%#panic:\ %m,
|
||||
\%A%f:%l:%c:\ %m,
|
||||
\%A%f:%l:\ %m,
|
||||
\%C%*\\s%m,
|
||||
\%-G%.%#
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
||||
|
||||
" vim:ts=4:sw=4:et
|
@ -0,0 +1,574 @@
|
||||
*vim-go.txt* Go development plugin
|
||||
*vim-go*
|
||||
|
||||
===============================================================================
|
||||
# #
|
||||
# ## ## #### ## ## ###### ####### #
|
||||
# ## ## ## ### ### ## ## ## ## #
|
||||
# ## ## ## #### #### ## ## ## #
|
||||
# ## ## ## ## ### ## ####### ## #### ## ## #
|
||||
# ## ## ## ## ## ## ## ## ## #
|
||||
# ## ## ## ## ## ## ## ## ## #
|
||||
# ### #### ## ## ###### ####### #
|
||||
# #
|
||||
===============================================================================
|
||||
CONTENTS *go-contents*
|
||||
|
||||
1. Intro........................................|go-intro|
|
||||
2. Install......................................|go-install|
|
||||
3. Commands.....................................|go-commands|
|
||||
4. Settings.....................................|go-settings|
|
||||
5. Mappings.....................................|go-mappings|
|
||||
6. Troubleshooting..............................|go-troubleshooting|
|
||||
7. Credits......................................|go-credits|
|
||||
|
||||
===============================================================================
|
||||
INTRO *go-intro*
|
||||
|
||||
Go (golang) support for Vim. vim-go installs automatically all necessary
|
||||
binaries for providing seamless Vim integration. It comes with pre-defined
|
||||
sensible settings (like auto gofmt on save), has autocomplete, snippet
|
||||
support, improved syntax highlighting, go toolchain commands, etc... It's
|
||||
highly customizable and each individual feature can be disabled/enabled
|
||||
easily.
|
||||
|
||||
* Improved Syntax highlighting, such as Functions, Operators, Methods..
|
||||
* Auto completion support via `gocode`
|
||||
* Better `gofmt` on save, keeps cursor position and doesn't break your undo
|
||||
history
|
||||
* Go to symbol/declaration with `godef`
|
||||
* Automatically import packages via `goimports`
|
||||
* Compile and `go build` your package, install it with `go install`
|
||||
* `go run` quickly your current file/files
|
||||
* Run `go test` and see any errors in quickfix window
|
||||
* Lint your code with `golint`
|
||||
* Run your code trough `go vet` to catch static errors.
|
||||
* Advanced source analysis tool with `oracle`
|
||||
* Precise type-safe renaming of identifiers with `gorename`
|
||||
* List all source files and dependencies
|
||||
* Checking with `errcheck` for unchecked errors.
|
||||
* Integrated and improved snippets. Supports `ultisnips` or `neosnippet`
|
||||
* Share your current code to play.golang.org
|
||||
* Type information about the underlying identifier
|
||||
* Tagbar support to show tags of the source code in a sidebar with `gotags`
|
||||
|
||||
===============================================================================
|
||||
INSTALL *go-install*
|
||||
|
||||
If you use pathogen, just clone it into your bundle directory: >
|
||||
|
||||
$ cd ~/.vim/bundle
|
||||
$ git clone https://github.com/fatih/vim-go.git
|
||||
<
|
||||
|
||||
For Vundle add this line to your vimrc:
|
||||
>
|
||||
Plugin 'fatih/vim-go'
|
||||
<
|
||||
and execute `:PluginInstall` (or `:BundleInstall` for older versions of Vundle)
|
||||
|
||||
|
||||
Please be sure all necessary binares are installed (such as `gocode`, `godef`,
|
||||
`goimports`, etc..). You can easily install them with the included
|
||||
|GoInstallBinaries|. Those binaries will be automatically downloaded and
|
||||
installed to your `$GOBIN` environment (if not set it will use `$GOPATH/bin`).
|
||||
It requires `git` and `hg` for fetching the individual Go packages.
|
||||
|
||||
* Autocompletion is enabled by default via `<C-x><C-o>`, to get real-time
|
||||
completion (completion by type) install:
|
||||
https://github.com/Valloric/YouCompleteMe or
|
||||
https://github.com/Shougo/neocomplete.vim
|
||||
* To get displayed source code tag informations on a sidebar install
|
||||
https://github.com/majutsushi/tagbar.
|
||||
* For snippet feature install:
|
||||
https://github.com/SirVer/ultisnips or
|
||||
https://github.com/Shougo/neosnippet.vim.
|
||||
|
||||
===============================================================================
|
||||
COMMANDS *go-commands*
|
||||
|
||||
*:GoImport*
|
||||
:GoImport [path]
|
||||
|
||||
Import ensures that the provided package {path} is imported in the current
|
||||
Go buffer, using proper style and ordering. If {path} is already being
|
||||
imported, an error will be displayed and the buffer will be untouched.
|
||||
|
||||
*:GoImportAs*
|
||||
:GoImportAs [localname] [path]
|
||||
|
||||
Same as Import, but uses a custom local name for the package.
|
||||
|
||||
*:GoDrop*
|
||||
:GoDrop [path]
|
||||
|
||||
Remove the import line for the provided package {path}, if present in the
|
||||
current Go buffer. If {path} is not being imported, an error will be
|
||||
displayed and the buffer will be untouched.
|
||||
|
||||
*:GoLint*
|
||||
:GoLint
|
||||
|
||||
Run golint for the current Go file.
|
||||
|
||||
*:GoDoc*
|
||||
:GoDoc [word]
|
||||
|
||||
Open the relevant GoDoc in split window for either the word[s] passed to
|
||||
the command or by default, the word under the cursor.
|
||||
|
||||
*:GoDocBrowser*
|
||||
:GoDocBrowser [word]
|
||||
|
||||
Open the relevant GoDoc in browser for either the word[s] passed to the
|
||||
command or by default, the word under the cursor.
|
||||
|
||||
*:GoFmt*
|
||||
:GoFmt
|
||||
|
||||
Filter the current Go buffer through gofmt. It tries to preserve cursor
|
||||
position and avoids replacing the buffer with stderr output.
|
||||
|
||||
*:GoImports*
|
||||
:GoImports
|
||||
|
||||
Filter the current Go buffer through goimports (needs to be installed).
|
||||
`goimports` automatically discards/add import path based on the code. Like
|
||||
|GoFmt|, It tries to preserve cursor position and avoids replacing the
|
||||
buffer with stderr output.
|
||||
|
||||
*:GoPlay*
|
||||
:[range]GoPlay
|
||||
|
||||
Share snippet to play.golang.org. If no [range] is given it shares
|
||||
the whole file, otherwise the selected lines are shared. Snippet URL
|
||||
is copied to system clipboard if Vim is compiled with 'clipboard' or
|
||||
'xterm-clipboard' otherwise it's get yanked into the `""` register.
|
||||
|
||||
*:GoVet*
|
||||
:GoVet
|
||||
|
||||
Run `go vet` for the directory under your current file. Vet examines Go
|
||||
source code and reports suspicious constructs, such as Printf calls whose
|
||||
arguments do not align with the format string. Vet uses heuristics that do not
|
||||
guarantee all reports are genuine problems, but it can find errors not caught
|
||||
by the compilers.
|
||||
|
||||
*:GoDef*
|
||||
:GoDef [identifier]
|
||||
|
||||
Goto declaration/definition for the given [identifier]. If no argument is
|
||||
given, it will jump to the declaration under the cursor. By default the
|
||||
mapping `gd` is enabled to invoke GoDef for the identifier under the cursor.
|
||||
See |g:go_def_mapping_enabled| to disable it.
|
||||
|
||||
*:GoRun*
|
||||
:GoRun[!] [expand]
|
||||
|
||||
Build and run your current main package. By default all main files for the
|
||||
current file is used. If an argument is passed, 'expand' is used as file
|
||||
selector. For example use `:GoRun %` to select the current file only.
|
||||
|
||||
If [!] is not given the first error is jumped to.
|
||||
|
||||
*:GoBuild*
|
||||
:GoBuild[!] [options]
|
||||
|
||||
Build your package with `go build`. It automatically builds only the files
|
||||
that depends on the current file. GoBuild doesn't produce a result file.
|
||||
Use 'make' to create a result file.
|
||||
|
||||
You may optionally pass any valid go build flags/options. For a full list
|
||||
please see `go help build`.
|
||||
|
||||
If [!] is not given the first error is jumped to.
|
||||
|
||||
*:GoInfo*
|
||||
:GoInfo
|
||||
Show type information about the identifer under the cursor. For example
|
||||
putting it above a function call is going to show the full function
|
||||
signature. It uses gocode to get the type informations.
|
||||
|
||||
|
||||
*:GoInstall*
|
||||
:GoInstall
|
||||
|
||||
Install your package with `go install`.
|
||||
|
||||
*:GoTest*
|
||||
:GoTest [expand]
|
||||
|
||||
Test your _test.go files via in your current directory. Errors are
|
||||
populated in quickfix window. If an argument is passed, 'expand' is used
|
||||
as file selector (useful for cases like `:GoTest ./...`).
|
||||
|
||||
*:GoCoverage*
|
||||
:GoCoverage
|
||||
|
||||
Create a coverage profile and open a browser to display the annotated
|
||||
source code of the current package.
|
||||
|
||||
*:GoErrCheck*
|
||||
:GoErrCheck
|
||||
|
||||
Check for unchecked errors in you current package. Errors are populated in
|
||||
quickfix window.
|
||||
|
||||
*:GoFiles*
|
||||
:GoFiles
|
||||
|
||||
Show source files that depends for the current package
|
||||
|
||||
*:GoDeps*
|
||||
:GoDeps
|
||||
|
||||
Show dependencies for the current package
|
||||
|
||||
*:GoInstallBinaries*
|
||||
:GoInstallBinaries
|
||||
|
||||
Download and Install all necessary Go tool binaries such as `godef`,
|
||||
`goimports`, `gocode`, etc.. under `g:go_bin_path`
|
||||
|
||||
*:GoUpdateBinaries*
|
||||
:GoUpdateBinaries
|
||||
|
||||
Download and Update previously installed Go tool binaries such as `godef`,
|
||||
`goimports`, `gocode`, etc.. under `g:go_bin_path`. This can be used to
|
||||
update the necessary Go binaries.
|
||||
|
||||
*:GoImplements*
|
||||
:GoImplements
|
||||
|
||||
Show 'implements' relation for a selected package. A list of interfaces
|
||||
for the type under the cursor (or selected package) is shown in a custom
|
||||
window. Hit `<enter>` to jump in a new tab or close it via `<c-c>`.
|
||||
|
||||
*:GoRename*
|
||||
:GoRename [to]
|
||||
|
||||
Rename the identifier under the cursor to the desired new name. If no
|
||||
argument is given a prompt will ask for the desired identifier.
|
||||
|
||||
===============================================================================
|
||||
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)`: >
|
||||
|
||||
au FileType go nmap <leader>r <Plug>(go-run)
|
||||
|
||||
As always one is free to create more advanced mappings or functions based
|
||||
with |go-commands|. Available <Plug> keys are:
|
||||
|
||||
*(go-run)*
|
||||
|
||||
Calls `go run` for the current file
|
||||
|
||||
|
||||
*(go-build)*
|
||||
|
||||
Calls `go build` for the current package
|
||||
|
||||
|
||||
*(go-info)*
|
||||
|
||||
Shows type information for the word under the cursor
|
||||
|
||||
|
||||
*(go-install)*
|
||||
|
||||
Calls `go install` for the current package
|
||||
|
||||
|
||||
*(go-test)*
|
||||
|
||||
Calls `go test` for the current package
|
||||
|
||||
*(go-coverage)*
|
||||
|
||||
Calls `go test -coverprofile-temp.out` for the current package
|
||||
|
||||
*(go-vet)*
|
||||
|
||||
Calls `go vet` for the current package
|
||||
|
||||
|
||||
*(go-files)*
|
||||
|
||||
Show source files that depends for the current package
|
||||
|
||||
|
||||
*(go-deps)*
|
||||
|
||||
Show dependencies for the current package
|
||||
|
||||
*(go-doc)*
|
||||
|
||||
Show the relevant GoDoc for the word under the cursor in a split window
|
||||
leftabove (default mode).
|
||||
|
||||
*(go-doc-split)*
|
||||
|
||||
Show the relevant GoDoc for the word under the cursor in a split window.
|
||||
|
||||
|
||||
*(go-doc-vertical)*
|
||||
|
||||
Show the relevant GoDoc for the word under the cursor in a vertical split
|
||||
window.
|
||||
|
||||
|
||||
*(go-doc-tab)*
|
||||
|
||||
Show the relevant GoDoc for the word under the cursor in a tab window.
|
||||
|
||||
|
||||
*(go-doc-browser)*
|
||||
|
||||
Show the relevant GoDoc for the word under in browser
|
||||
|
||||
*(go-def)*
|
||||
|
||||
Goto declaration/definition. Results are shown in the current buffer.
|
||||
|
||||
|
||||
*(go-def-split)*
|
||||
|
||||
Goto declaration/definition. Results are shown in a split window.
|
||||
|
||||
|
||||
*(go-def-vertical)*
|
||||
|
||||
Goto declaration/definition. Results are shown in a vertical split window.
|
||||
|
||||
|
||||
*(go-def-tab)*
|
||||
|
||||
Goto declaration/definition. Results are shown in a tab window.
|
||||
|
||||
*(go-implements)*
|
||||
|
||||
Show the interfaces that the type under the cursor implements.
|
||||
|
||||
*(go-rename)*
|
||||
|
||||
Rename the identifier under the cursor to the desired new name
|
||||
|
||||
|
||||
|
||||
===============================================================================
|
||||
SETTINGS *go-settings*
|
||||
|
||||
*'g:go_play_browser_command'*
|
||||
|
||||
Use this option to change the browser that is used to open the snippet url
|
||||
posted to play.golang.org with |:GoPlay| or for the relevant documentation
|
||||
used with |:GoDocBrowser|. By default it tries to find it automatically for
|
||||
the current OS. >
|
||||
|
||||
let g:play_browser_command = ''
|
||||
<
|
||||
*'g:go_play_open_browser'*
|
||||
|
||||
Use this option to open browser after posting the snippet to play.golang.org
|
||||
with |:GoPlay|. By default it's enabled. >
|
||||
|
||||
let g:go_play_open_browser = 1
|
||||
<
|
||||
*'g:go_auto_type_info'*
|
||||
|
||||
Use this option to show the type info (|:GoInfo|) for the word under the cursor
|
||||
automatically. Whenever the cursor changes the type info will be updated.
|
||||
By default it's disabled >
|
||||
|
||||
let g:go_auto_type_info = 0
|
||||
<
|
||||
*'g:go_fmt_autosave'*
|
||||
|
||||
Use this option to auto |:GoFmt| on save. By default it's enabled >
|
||||
|
||||
let g:go_fmt_autosave = 1
|
||||
<
|
||||
*'g:go_fmt_command'*
|
||||
|
||||
Use this option to define which tool is used to gofmt. By default `gofmt` is
|
||||
used >
|
||||
|
||||
let g:go_fmt_command = "gofmt"
|
||||
<
|
||||
*'g:go_fmt_options'*
|
||||
|
||||
Use this option to add additional options to the |g:go_fmt_command|. Default
|
||||
is empty. >
|
||||
|
||||
let g:go_fmt_options = ''
|
||||
<
|
||||
|
||||
*'g:go_fmt_fail_silently'*
|
||||
|
||||
Use this option to disable showing a quickfix window when |g:go_fmt_command|
|
||||
fails. By default it's disabled. >
|
||||
|
||||
let g:go_fmt_fail_silently = 0
|
||||
<
|
||||
*'g:go_doc_keywordprg_enabled'*
|
||||
|
||||
Use this option to change the enable GoDoc to run on words under the cursor
|
||||
with the default K , keywordprg shortcut. This shortcut is by default set to
|
||||
use the program man. However in go using godoc is more idiomatic. Default is
|
||||
enabled. >
|
||||
|
||||
let g:go_doc_keywordprg_enabled = 1
|
||||
<
|
||||
*'g:go_def_mapping_enabled'*
|
||||
|
||||
Use this option to enabled/ disable the default mapping (`gd`) for GoDef
|
||||
enabled. Disabling it allows you to map something else to the mapping `gd`.
|
||||
Default is enabled. >
|
||||
|
||||
let g:go_def_mapping_enabled = 1
|
||||
<
|
||||
*'g:go_doc_command'*
|
||||
|
||||
Use this option to define which tool is used to godoc. By default `godoc` is
|
||||
used >
|
||||
|
||||
let g:go_doc_command = "godoc"
|
||||
<
|
||||
*'g:go_doc_options'*
|
||||
|
||||
Use this option to add additional options to the |g:go_doc_command|. Default
|
||||
is empty. >
|
||||
|
||||
let g:go_doc_options = ''
|
||||
|
||||
< *'g:go_bin_path'*
|
||||
|
||||
Use this option to change default path for vim-go tools when using
|
||||
|GoInstallBinaries| and |GoUpdateBinaries|. If not set `$GOBIN` or
|
||||
`$GOPATH/bin` is used. >
|
||||
|
||||
let g:go_bin_path = ""
|
||||
<
|
||||
*'g:go_snippet_engine'*
|
||||
|
||||
Use this option to define the default snippet engine. By default "ultisnips"
|
||||
is used. Use "neosnippet" for neosnippet.vim: >
|
||||
|
||||
let g:go_snippet_engine = "ultisnips"
|
||||
<
|
||||
|
||||
*'g:go_highlight_array_whitespace_error'*
|
||||
|
||||
Highlights white space after "[]". >
|
||||
|
||||
let g:go_highlight_array_whitespace_error = 1
|
||||
<
|
||||
|
||||
*'g:go_highlight_chan_whitespace_error'*
|
||||
|
||||
Highlights white space around the communications operator that don't follow
|
||||
the standard style. >
|
||||
|
||||
let g:go_highlight_chan_whitespace_error = 1
|
||||
<
|
||||
|
||||
*'g:go_highlight_extra_types'*
|
||||
|
||||
Highlights commonly used library types (io.Reader, etc.). >
|
||||
|
||||
let g:go_highlight_extra_types = 1
|
||||
<
|
||||
|
||||
*'g:go_highlight_space_tab_error'*
|
||||
|
||||
Highlights instances of tabs following spaces. >
|
||||
|
||||
let g:go_highlight_space_tab_error = 1
|
||||
<
|
||||
*'g:go_highlight_trailing_whitespace_error'*
|
||||
|
||||
Highlights trailing white space. >
|
||||
|
||||
let g:go_highlight_trailing_whitespace_error = 1
|
||||
|
||||
<
|
||||
*'g:go_highlight_operators'*
|
||||
|
||||
Highlights operators such as `:=` , `==`, `-=`, etc ...By default it's
|
||||
disabled. >
|
||||
|
||||
let g:go_highlight_operators = 0
|
||||
<
|
||||
*'g:go_highlight_functions'*
|
||||
|
||||
Highlights function names. By default it's disabled. >
|
||||
|
||||
let g:go_highlight_functions = 0
|
||||
<
|
||||
*'g:go_highlight_methods'*
|
||||
|
||||
Highlights method names. By default it's disabled. >
|
||||
|
||||
let g:go_highlight_methods = 0
|
||||
<
|
||||
*'g:go_highlight_structs'*
|
||||
|
||||
Highlights struct names. By default it's disabled. >
|
||||
|
||||
let g:go_highlight_structs = 0
|
||||
<
|
||||
===============================================================================
|
||||
TROUBLESHOOTING *go-troubleshooting*
|
||||
|
||||
I'm using Fish shell but have some problems using Vim-go~
|
||||
|
||||
First environment variables in Fish are applied differently, it should be like:
|
||||
>
|
||||
set -x GOPATH /your/own/gopath
|
||||
<
|
||||
Second, Vim needs a POSIX compatible shell (more info here:
|
||||
https://github.com/dag/vim-fish#teach-a-vim-to-fish). If you use Fish to open
|
||||
vim, it will make certainx shell based commands fail (means vim-go will fail
|
||||
too). To overcome this problem change the default shell by adding the
|
||||
following into your .vimrc (on the top of the file):
|
||||
>
|
||||
if $SHELL =~ 'fish'
|
||||
set shell='/bin/sh'
|
||||
endif
|
||||
<
|
||||
or
|
||||
>
|
||||
set shell='/bin/sh'
|
||||
>
|
||||
|
||||
I'm seeing weirds errors during the startup~
|
||||
|
||||
If you see errors like this:
|
||||
>
|
||||
Error installing code.google.com/p/go.tools/cmd/goimports:
|
||||
Error installing code.google.com/p/rog-go/exp/cmd/godef:
|
||||
<
|
||||
that means your local Go setup is broken or the remote website is down. For
|
||||
example sometimes code.google.com times out. To test, just execute a simple go
|
||||
get:
|
||||
|
||||
>
|
||||
go get code.google.com/p/go.tools/cmd/goimports
|
||||
<
|
||||
You'll see a more detailed error. If this works, vim-go will work too.
|
||||
|
||||
===============================================================================
|
||||
CREDITS *go-credits*
|
||||
|
||||
* Go Authors for offical vim plugins
|
||||
* Gocode, Godef, Golint, Oracle, Goimports, Errcheck projects and authors of
|
||||
those projects.
|
||||
* Other vim-plugins, thanks for inspiration (vim-golang, go.vim, vim-gocode,
|
||||
vim-godef)
|
||||
* vim-go contributors: https://github.com/fatih/vim-go/graphs/contributors
|
||||
|
||||
|
||||
vim:ft=help:et:ts=2:sw=2:sts=2:norl
|
@ -0,0 +1,23 @@
|
||||
" We take care to preserve the user's fileencodings and fileformats,
|
||||
" because those settings are global (not buffer local), yet we want
|
||||
" to override them for loading Go files, which are defined to be UTF-8.
|
||||
let s:current_fileformats = ''
|
||||
let s:current_fileencodings = ''
|
||||
|
||||
" define fileencodings to open as utf-8 encoding even if it's ascii.
|
||||
function! s:gofiletype_pre()
|
||||
let s:current_fileformats = &g:fileformats
|
||||
let s:current_fileencodings = &g:fileencodings
|
||||
set fileencodings=utf-8 fileformats=unix
|
||||
setlocal filetype=go
|
||||
endfunction
|
||||
|
||||
" restore fileencodings as others
|
||||
function! s:gofiletype_post()
|
||||
let &g:fileformats = s:current_fileformats
|
||||
let &g:fileencodings = s:current_fileencodings
|
||||
endfunction
|
||||
|
||||
au BufNewFile *.go setlocal filetype=go fileencoding=utf-8 fileformat=unix
|
||||
au BufRead *.go call s:gofiletype_pre()
|
||||
au BufReadPost *.go call s:gofiletype_post()
|
@ -0,0 +1,39 @@
|
||||
" Copyright 2013 The Go Authors. All rights reserved.
|
||||
" Use of this source code is governed by a BSD-style
|
||||
" license that can be found in the LICENSE file.
|
||||
"
|
||||
" go.vim: Vim filetype plugin for Go.
|
||||
|
||||
if exists("b:did_ftplugin")
|
||||
finish
|
||||
endif
|
||||
let b:did_ftplugin = 1
|
||||
|
||||
let b:undo_ftplugin = "setl fo< com< cms<"
|
||||
|
||||
setlocal formatoptions-=t
|
||||
|
||||
setlocal comments=s1:/*,mb:*,ex:*/,://
|
||||
setlocal commentstring=//\ %s
|
||||
|
||||
setlocal noexpandtab
|
||||
|
||||
compiler go
|
||||
|
||||
" Set gocode completion
|
||||
setlocal omnifunc=go#complete#Complete
|
||||
|
||||
if get(g:, "go_doc_keywordprg_enabled", 1)
|
||||
" keywordprg doesn't allow to use vim commands, override it
|
||||
nnoremap <buffer> <silent> K :GoDoc<cr>
|
||||
endif
|
||||
|
||||
if get(g:, "go_def_mapping_enabled", 1)
|
||||
nnoremap <buffer> <silent> gd :GoDef<cr>
|
||||
endif
|
||||
|
||||
if get(g:, "go_auto_type_info", 0)
|
||||
setlocal updatetime=800
|
||||
endif
|
||||
|
||||
" vim:ts=4:sw=4:et
|
@ -0,0 +1,92 @@
|
||||
if exists("g:go_loaded_commands")
|
||||
finish
|
||||
endif
|
||||
let g:go_loaded_commands = 1
|
||||
|
||||
|
||||
" Some handy plug mappings
|
||||
nnoremap <silent> <Plug>(go-run) :<C-u>call go#cmd#Run(expand('%'))<CR>
|
||||
nnoremap <silent> <Plug>(go-build) :<C-u>call go#cmd#Build('')<CR>
|
||||
nnoremap <silent> <Plug>(go-install) :<C-u>call go#cmd#Install()<CR>
|
||||
nnoremap <silent> <Plug>(go-test) :<C-u>call go#cmd#Test('')<CR>
|
||||
nnoremap <silent> <Plug>(go-coverage) :<C-u>call go#cmd#Coverage('')<CR>
|
||||
nnoremap <silent> <Plug>(go-vet) :<C-u>call go#cmd#Vet()<CR>
|
||||
nnoremap <silent> <Plug>(go-files) :<C-u>call go#tool#Files()<CR>
|
||||
nnoremap <silent> <Plug>(go-deps) :<C-u>call go#tool#Deps()<CR>
|
||||
nnoremap <silent> <Plug>(go-info) :<C-u>call go#complete#Info()<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-rename) :<C-u>call go#rename#Rename()<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-doc) :<C-u>call go#doc#Open("leftabove new")<CR>
|
||||
nnoremap <silent> <Plug>(go-doc-tab) :<C-u>call go#doc#Open("tabnew")<CR>
|
||||
nnoremap <silent> <Plug>(go-doc-vertical) :<C-u>call go#doc#Open("vnew")<CR>
|
||||
nnoremap <silent> <Plug>(go-doc-split) :<C-u>call go#doc#Open("split")<CR>
|
||||
nnoremap <silent> <Plug>(go-doc-browser) :<C-u>call go#doc#OpenBrowser()<CR>
|
||||
|
||||
|
||||
" gorename
|
||||
command! -nargs=? GoRename call go#rename#Rename(<f-args>)
|
||||
|
||||
" oracle
|
||||
command! -range=% GoImplements call go#oracle#Implements(<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()
|
||||
|
||||
" cmd
|
||||
command! -nargs=* -bang GoRun call go#cmd#Run(<bang>0,<f-args>)
|
||||
command! -nargs=* -bang GoBuild call go#cmd#Build(<bang>0,<f-args>)
|
||||
command! -nargs=* GoInstall call go#cmd#Install(<f-args>)
|
||||
command! -nargs=* GoTest call go#cmd#Test(<f-args>)
|
||||
command! -nargs=* GoCoverage call go#cmd#Coverage(<f-args>)
|
||||
command! -nargs=0 GoVet call go#cmd#Vet()
|
||||
|
||||
" -- play
|
||||
command! -nargs=0 -range=% GoPlay call go#play#Share(<count>, <line1>, <line2>)
|
||||
|
||||
" -- def
|
||||
command! -nargs=* -range GoDef :call go#def#Jump(<f-args>)
|
||||
|
||||
" -- doc
|
||||
command! -nargs=* -range -complete=customlist,go#package#Complete GoDoc call go#doc#Open('leftabove new', <f-args>)
|
||||
command! -nargs=* -range -complete=customlist,go#package#Complete GoDocBrowser call go#doc#OpenBrowser(<f-args>)
|
||||
|
||||
" -- fmt
|
||||
command! -nargs=0 GoFmt call go#fmt#Format(-1)
|
||||
command! -nargs=0 GoImports call go#fmt#Format(1)
|
||||
|
||||
" -- import
|
||||
command! -nargs=? -complete=customlist,go#package#Complete GoDrop call go#import#SwitchImport(0, '', <f-args>)
|
||||
command! -nargs=1 -complete=customlist,go#package#Complete GoImport call go#import#SwitchImport(1, '', <f-args>)
|
||||
command! -nargs=* -complete=customlist,go#package#Complete GoImportAs call go#import#SwitchImport(1, <f-args>)
|
||||
|
||||
" -- lint
|
||||
command! GoLint call go#lint#Run()
|
||||
|
||||
" -- errcheck
|
||||
command! -nargs=? -complete=customlist,go#package#Complete GoErrCheck call go#errcheck#Run(<f-args>)
|
||||
|
||||
" Disable all commands until they are fully integrated.
|
||||
"
|
||||
" command! -range=% GoOracleDescribe call go#oracle#Describe(<count>)
|
||||
" command! -range=% GoOracleCallees call go#oracle#Callees(<count>)
|
||||
" command! -range=% GoOracleCallers call go#oracle#Callers(<count>)
|
||||
" command! -range=% GoOracleCallgraph call go#oracle#Callgraph(<count>)
|
||||
" command! -range=% GoOracleCallstack call go#oracle#Callstack(<count>)
|
||||
" command! -range=% GoOracleFreevars call go#oracle#Freevars(<count>)
|
||||
" command! -range=% GoOraclePeers call go#oracle#Peers(<count>)
|
||||
" command! -range=% GoOracleReferrers call go#oracle#Referrers(<count>)
|
||||
|
||||
" vim:ts=4:sw=4:et
|
||||
"
|
||||
|
@ -0,0 +1,36 @@
|
||||
if exists("g:go_loaded_gosnippets")
|
||||
finish
|
||||
endif
|
||||
let g:go_loaded_gosnippets = 1
|
||||
|
||||
" by default UltiSnips
|
||||
if !exists("g:go_snippet_engine")
|
||||
let g:go_snippet_engine = "ultisnips"
|
||||
endif
|
||||
|
||||
function! s:GoUltiSnips()
|
||||
if globpath(&rtp, 'plugin/UltiSnips.vim') == ""
|
||||
return
|
||||
endif
|
||||
|
||||
if !exists("g:UltiSnipsSnippetDirectories")
|
||||
let g:UltiSnipsSnippetDirectories = ["gosnippets/UltiSnips"]
|
||||
else
|
||||
let g:UltiSnipsSnippetDirectories += ["gosnippets/UltiSnips"]
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:GoNeosnippet()
|
||||
if globpath(&rtp, 'plugin/neosnippet.vim') == ""
|
||||
return
|
||||
endif
|
||||
|
||||
let g:neosnippet#enable_snipmate_compatibility = 1
|
||||
exec 'NeoSnippetSource' globpath(&rtp, 'gosnippets/snippets/go.snip')
|
||||
endfunction
|
||||
|
||||
if g:go_snippet_engine == "ultisnips"
|
||||
call s:GoUltiSnips()
|
||||
elseif g:go_snippet_engine == "neosnippet"
|
||||
call s:GoNeosnippet()
|
||||
endif
|
@ -0,0 +1,55 @@
|
||||
" Check if tagbar is installed under plugins or is directly under rtp
|
||||
" this covers pathgen + Vundle/Bundle
|
||||
"
|
||||
" Also make sure the ctags command exists
|
||||
"
|
||||
if !executable('ctags')
|
||||
finish
|
||||
elseif globpath(&rtp, 'plugin/tagbar.vim') == ""
|
||||
finish
|
||||
endif
|
||||
|
||||
if !exists("g:go_gotags_bin")
|
||||
let g:go_gotags_bin = "gotags"
|
||||
endif
|
||||
|
||||
|
||||
function! s:SetTagbar()
|
||||
let bin_path = go#tool#BinPath(g:go_gotags_bin)
|
||||
if empty(bin_path)
|
||||
return
|
||||
endif
|
||||
|
||||
if !exists("g:tagbar_type_go")
|
||||
let g:tagbar_type_go = {
|
||||
\ 'ctagstype' : 'go',
|
||||
\ 'kinds' : [
|
||||
\ 'p:package',
|
||||
\ 'i:imports:1',
|
||||
\ 'c:constants',
|
||||
\ 'v:variables',
|
||||
\ 't:types',
|
||||
\ 'n:interfaces',
|
||||
\ 'w:fields',
|
||||
\ 'e:embedded',
|
||||
\ 'm:methods',
|
||||
\ 'r:constructor',
|
||||
\ 'f:functions'
|
||||
\ ],
|
||||
\ 'sro' : '.',
|
||||
\ 'kind2scope' : {
|
||||
\ 't' : 'ctype',
|
||||
\ 'n' : 'ntype'
|
||||
\ },
|
||||
\ 'scope2kind' : {
|
||||
\ 'ctype' : 't',
|
||||
\ 'ntype' : 'n'
|
||||
\ },
|
||||
\ 'ctagsbin' : expand(bin_path),
|
||||
\ 'ctagsargs' : '-sort -silent'
|
||||
\ }
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
call s:SetTagbar()
|
@ -0,0 +1,241 @@
|
||||
# Snippets for Go
|
||||
|
||||
priority -10
|
||||
|
||||
# when to abbriviate and when not?
|
||||
# b doesn't work here, because it ignores whitespace
|
||||
# optional local name?
|
||||
snippet import "Import declaration" b
|
||||
import (
|
||||
"${1:package}"
|
||||
)
|
||||
endsnippet
|
||||
|
||||
snippet package "Package declaration" b
|
||||
// Package $1 provides ${2:...}
|
||||
package ${1:main}
|
||||
${0:${VISUAL}}
|
||||
endsnippet
|
||||
|
||||
# Mostly converted from: https://github.com/AlanQuatermain/go-tmbundle
|
||||
snippet /^cons/ "Constants declaration" r
|
||||
const (
|
||||
${1:constant}${2/(.+)/ /}${2:type} = ${0:value}
|
||||
)
|
||||
endsnippet
|
||||
|
||||
snippet /^con/ "Constant declaration" r
|
||||
const ${1:name}${2/(.+)/ /}${2:type} = ${0:value}
|
||||
endsnippet
|
||||
|
||||
snippet iota "Iota constant generator" b
|
||||
const (
|
||||
${1:constant}${2/(.+)/ /}${2:type} = iota
|
||||
)
|
||||
endsnippet
|
||||
|
||||
snippet struct "Struct declaration" b
|
||||
type ${1:Struct} struct {
|
||||
${0:${VISUAL}}
|
||||
}
|
||||
endsnippet
|
||||
|
||||
snippet interface "Interface declaration" b
|
||||
type ${1:Interface} interface {
|
||||
${0:${VISUAL}}
|
||||
}
|
||||
endsnippet
|
||||
|
||||
# statements
|
||||
snippet for "For loop" b
|
||||
for ${1:condition} {
|
||||
${0:${VISUAL}}
|
||||
}
|
||||
endsnippet
|
||||
|
||||
snippet fori "Integer for loop" b
|
||||
for ${1:i} := 0; $1 < ${2:N}; $1++ {
|
||||
${0:${VISUAL}}
|
||||
}
|
||||
endsnippet
|
||||
|
||||
snippet forr "For range loop" b
|
||||
for ${2:name} := range ${1:collection} {
|
||||
${0:${VISUAL}}
|
||||
}
|
||||
endsnippet
|
||||
|
||||
snippet if "If statement" b
|
||||
if ${1:condition}${1/(.+)/ /}{
|
||||
${0:${VISUAL}}
|
||||
}
|
||||
endsnippet
|
||||
|
||||
snippet switch "Switch statement" b
|
||||
switch ${1:expression}${1/(.+)/ /}{
|
||||
case${0}
|
||||
}
|
||||
endsnippet
|
||||
|
||||
snippet select "Select statement" b
|
||||
select {
|
||||
case${0}
|
||||
}
|
||||
endsnippet
|
||||
|
||||
snippet case "Case clause" b
|
||||
case ${1:condition}:
|
||||
${0:${VISUAL}}
|
||||
endsnippet
|
||||
|
||||
snippet default "Default clause" b
|
||||
default:
|
||||
${0:${VISUAL}}
|
||||
endsnippet
|
||||
|
||||
# functions
|
||||
|
||||
global !p
|
||||
|
||||
import re
|
||||
|
||||
# Automatically wrap return types with parentheses
|
||||
|
||||
def return_values(s):
|
||||
# remove everything wrapped in parentheses
|
||||
s = re.sub("\(.*?\)|\([^)]*$", "", s)
|
||||
return len(s.split(","))
|
||||
|
||||
def opening_par(snip, pos):
|
||||
if return_values(t[pos]) > 1 and not t[pos].startswith("("):
|
||||
snip.rv = "("
|
||||
else:
|
||||
snip.rv = ""
|
||||
|
||||
def closing_par(snip, pos):
|
||||
if return_values(t[pos]) > 1:
|
||||
snip.rv = ")"
|
||||
else:
|
||||
snip.rv = ""
|
||||
|
||||
endglobal
|
||||
|
||||
snippet /^main/ "Main function" r
|
||||
func main() {
|
||||
${0:${VISUAL}}
|
||||
}
|
||||
endsnippet
|
||||
|
||||
snippet /^meth/ "Method" r
|
||||
func (${1:receiver} ${2:type}) ${3:name}(${4:params})${5/(.+)/ /}`!p opening_par(snip, 5)`$5`!p closing_par(snip, 5)` {
|
||||
${0:${VISUAL}}
|
||||
}
|
||||
endsnippet
|
||||
|
||||
snippet func "Function" b
|
||||
func ${1:name}(${2:params})${3/(.+)/ /}`!p opening_par(snip, 3)`$3`!p closing_par(snip, 3)` {
|
||||
${0:${VISUAL}}
|
||||
}
|
||||
endsnippet
|
||||
|
||||
snippet anon "Anonymous Function" !b
|
||||
${1:fn} := func() {
|
||||
${2}
|
||||
}
|
||||
endsnippet
|
||||
|
||||
# types and variables
|
||||
snippet map "Map type" b
|
||||
map[${1:keytype}]${2:valtype}
|
||||
endsnippet
|
||||
|
||||
snippet : "Short variable declaration :=" !b
|
||||
${1:name} := ${0:value}
|
||||
endsnippet
|
||||
|
||||
snippet var "Variable declaration" b
|
||||
var ${1:name}${2/(.+)/ /}${2:type}${3: = ${0:value}}
|
||||
endsnippet
|
||||
|
||||
snippet vars "Variables declaration" b
|
||||
var (
|
||||
${1:name}${2/(.+)/ /}${2:type}${3: = ${0:value} }
|
||||
)
|
||||
endsnippet
|
||||
|
||||
snippet json "JSON field"
|
||||
\`json:"${1:displayName}"\`
|
||||
endsnippet
|
||||
|
||||
snippet er "Error clause " !b
|
||||
if err != nil {
|
||||
${0}
|
||||
}
|
||||
endsnippet
|
||||
|
||||
snippet errn "Error return " !b
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
${0}
|
||||
endsnippet
|
||||
|
||||
snippet errn, "Error return with two return values" !b
|
||||
if err != nil {
|
||||
return ${1:nil}, err
|
||||
}
|
||||
${0}
|
||||
endsnippet
|
||||
|
||||
snippet errn,, "Error return with three return values" !b
|
||||
if err != nil {
|
||||
return ${1:nil}, ${2:nil}, err
|
||||
}
|
||||
${0}
|
||||
endsnippet
|
||||
|
||||
snippet ok "OK statement" !b
|
||||
if !ok {
|
||||
${0:${VISUAL}}
|
||||
}
|
||||
endsnippet
|
||||
|
||||
snippet gof "Anonymous Goroutine" !b
|
||||
go func() {
|
||||
${1}
|
||||
}()
|
||||
endsnippet
|
||||
|
||||
snippet def "Anonymous Defer" !b
|
||||
defer func() {
|
||||
${1}
|
||||
}()
|
||||
endsnippet
|
||||
|
||||
snippet ff "Fmt Printf debug" !b
|
||||
fmt.Printf("${1} %+v\n", $1)
|
||||
endsnippet
|
||||
|
||||
snippet fn "Fmt Println debug" !b
|
||||
fmt.Println("${1}")
|
||||
endsnippet
|
||||
|
||||
snippet lf "Log Printf debug" !b
|
||||
log.Printf("${1} %+v\n", $1)
|
||||
endsnippet
|
||||
|
||||
snippet ln "Log Println debug" !b
|
||||
log.Println("${1}")
|
||||
endsnippet
|
||||
|
||||
snippet make "make allocation" !b
|
||||
make(${1:Type}, ${2:size})${0}
|
||||
endsnippet
|
||||
|
||||
snippet test "test function" b
|
||||
func Test${1:Function}(t *testing.T) {
|
||||
${2}
|
||||
}
|
||||
endsnippet
|
||||
|
||||
# vim:ft=snippets:
|
@ -0,0 +1,243 @@
|
||||
# shorthand variable declaration
|
||||
snippet v
|
||||
${1} := ${2}
|
||||
# variable initialization
|
||||
snippet vr
|
||||
var ${1:t} ${0:string}
|
||||
# variable declaration
|
||||
snippet var
|
||||
var ${1} ${2} = ${3}
|
||||
# variables declaration
|
||||
snippet vars
|
||||
var (
|
||||
${1} ${2} = ${3}
|
||||
)
|
||||
# append
|
||||
snippet ap
|
||||
append(${1:slice}, ${0:value})
|
||||
# bool
|
||||
snippet bl
|
||||
bool
|
||||
# byte
|
||||
snippet bt
|
||||
byte
|
||||
# break
|
||||
snippet br
|
||||
break
|
||||
# channel
|
||||
snippet ch
|
||||
chan ${0:int}
|
||||
# case
|
||||
snippet cs
|
||||
case ${1:value}:
|
||||
${0}
|
||||
# const
|
||||
snippet c
|
||||
const ${1:NAME} = ${0:0}
|
||||
# constants with iota
|
||||
snippet co
|
||||
const (
|
||||
${1:NAME1} = iota
|
||||
${0:NAME2}
|
||||
)
|
||||
# continue
|
||||
snippet cn
|
||||
continue
|
||||
# defer
|
||||
snippet df
|
||||
defer ${0:func}()
|
||||
# defer recover
|
||||
snippet dfr
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
${0}
|
||||
}
|
||||
}()
|
||||
# gpl
|
||||
snippet gpl
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Copyright (C) ${1:Author}, `strftime("%Y")`
|
||||
*/
|
||||
|
||||
${0}
|
||||
# int
|
||||
snippet i
|
||||
int
|
||||
# import
|
||||
snippet im
|
||||
import (
|
||||
"${1:package}"
|
||||
)
|
||||
# interface
|
||||
snippet in
|
||||
interface{}
|
||||
# full interface snippet
|
||||
snippet inf
|
||||
interface ${1:name} {
|
||||
${2:/* methods */}
|
||||
}
|
||||
# if condition
|
||||
snippet if
|
||||
if ${1:/* condition */} {
|
||||
${2}
|
||||
}
|
||||
# else snippet
|
||||
snippet el
|
||||
else {
|
||||
${1}
|
||||
}
|
||||
# error snippet
|
||||
snippet ir
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
${0}
|
||||
# false
|
||||
snippet f
|
||||
false
|
||||
# fallthrough
|
||||
snippet ft
|
||||
fallthrough
|
||||
# float
|
||||
snippet fl
|
||||
float32
|
||||
# float32
|
||||
snippet f3
|
||||
float32
|
||||
# float64
|
||||
snippet f6
|
||||
float64
|
||||
# if else
|
||||
snippet ie
|
||||
if ${1:/* condition */} {
|
||||
${2}
|
||||
} else {
|
||||
${3}
|
||||
}
|
||||
${0}
|
||||
# for loop
|
||||
snippet fo
|
||||
for ${2:i} := 0; $2 < ${1:count}; $2${3:++} {
|
||||
${4}
|
||||
}
|
||||
${0}
|
||||
# for range loop
|
||||
snippet fr
|
||||
for ${1:k}, ${2:v} := range ${3} {
|
||||
${4}
|
||||
}
|
||||
${0}
|
||||
# function simple
|
||||
snippet fun
|
||||
func ${1:funcName}(${2}) ${3:error} {
|
||||
${4}
|
||||
}
|
||||
${0}
|
||||
# function on receiver
|
||||
snippet fum
|
||||
func (self ${1:type}) ${2:funcName}(${3}) ${4:error} {
|
||||
${5}
|
||||
}
|
||||
${0}
|
||||
# Fmt Printf debug
|
||||
snippet ff
|
||||
fmt.Printf("${1} %+v\n", ${0})
|
||||
# Fmt Println debug
|
||||
snippet fn
|
||||
fmt.Println("${1}")
|
||||
# log printf
|
||||
snippet lf
|
||||
log.Printf("%${1:s}", ${2:var})
|
||||
# log printf
|
||||
snippet lp
|
||||
log.Println("${1}")
|
||||
# make
|
||||
snippet mk
|
||||
make(${1:[]string}, ${0:0})
|
||||
# map
|
||||
snippet mp
|
||||
map[${1:string}]${0:int}
|
||||
# main()
|
||||
snippet main
|
||||
func main() {
|
||||
${1}
|
||||
}
|
||||
${0}
|
||||
# new
|
||||
snippet nw
|
||||
new(${0:type})
|
||||
# panic
|
||||
snippet pn
|
||||
panic("${0:msg}")
|
||||
# print
|
||||
snippet pr
|
||||
fmt.Printf("%${1:s}\n", ${2:var})
|
||||
# range
|
||||
snippet rn
|
||||
range ${0}
|
||||
# return
|
||||
snippet rt
|
||||
return ${0}
|
||||
# result
|
||||
snippet rs
|
||||
result
|
||||
# select
|
||||
snippet sl
|
||||
select {
|
||||
case ${1:v1} := <-${2:chan1}
|
||||
${3}
|
||||
case ${4:v2} := <-${5:chan2}
|
||||
${6}
|
||||
default:
|
||||
${0}
|
||||
}
|
||||
# string
|
||||
snippet sr
|
||||
string
|
||||
# struct
|
||||
snippet st
|
||||
struct ${1:name} {
|
||||
${2:/* data */}
|
||||
}
|
||||
${0}
|
||||
# switch
|
||||
snippet sw
|
||||
switch ${1:var} {
|
||||
case ${2:value1}:
|
||||
${3}
|
||||
case ${4:value2}:
|
||||
${5}
|
||||
default:
|
||||
${0}
|
||||
}
|
||||
snippet sp
|
||||
fmt.Sprintf("%${1:s}", ${2:var})
|
||||
# true
|
||||
snippet t
|
||||
true
|
||||
# goroutine named function
|
||||
snippet g
|
||||
go ${1:funcName}(${0})
|
||||
# goroutine anonymous function
|
||||
snippet ga
|
||||
go func(${1} ${2:type}) {
|
||||
${3:/* code */}
|
||||
}(${0})
|
||||
# test function
|
||||
snippet test
|
||||
func Test${1:Function}(t *testing.T) {
|
||||
${2}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
" Copyright 2011 The Go Authors. All rights reserved.
|
||||
" Use of this source code is governed by a BSD-style
|
||||
" license that can be found in the LICENSE file.
|
||||
"
|
||||
" indent/go.vim: Vim indent file for Go.
|
||||
"
|
||||
" TODO:
|
||||
" - function invocations split across lines
|
||||
" - general line splits (line ends in an operator)
|
||||
|
||||
if exists("b:did_indent")
|
||||
finish
|
||||
endif
|
||||
let b:did_indent = 1
|
||||
|
||||
" C indentation is too far off useful, mainly due to Go's := operator.
|
||||
" Let's just define our own.
|
||||
setlocal nolisp
|
||||
setlocal autoindent
|
||||
setlocal indentexpr=GoIndent(v:lnum)
|
||||
setlocal indentkeys+=<:>,0=},0=)
|
||||
|
||||
if exists("*GoIndent")
|
||||
finish
|
||||
endif
|
||||
|
||||
function! GoIndent(lnum)
|
||||
let prevlnum = prevnonblank(a:lnum-1)
|
||||
if prevlnum == 0
|
||||
" top of file
|
||||
return 0
|
||||
endif
|
||||
|
||||
" grab the previous and current line, stripping comments.
|
||||
let prevl = substitute(getline(prevlnum), '//.*$', '', '')
|
||||
let thisl = substitute(getline(a:lnum), '//.*$', '', '')
|
||||
let previ = indent(prevlnum)
|
||||
|
||||
let ind = previ
|
||||
|
||||
if prevl =~ '[({]\s*$'
|
||||
" previous line opened a block
|
||||
let ind += &sw
|
||||
endif
|
||||
if prevl =~# '^\s*\(case .*\|default\):$'
|
||||
" previous line is part of a switch statement
|
||||
let ind += &sw
|
||||
endif
|
||||
" TODO: handle if the previous line is a label.
|
||||
|
||||
if thisl =~ '^\s*[)}]'
|
||||
" this line closed a block
|
||||
let ind -= &sw
|
||||
endif
|
||||
|
||||
" Colons are tricky.
|
||||
" We want to outdent if it's part of a switch ("case foo:" or "default:").
|
||||
" We ignore trying to deal with jump labels because (a) they're rare, and
|
||||
" (b) they're hard to disambiguate from a composite literal key.
|
||||
if thisl =~# '^\s*\(case .*\|default\):$'
|
||||
let ind -= &sw
|
||||
endif
|
||||
|
||||
return ind
|
||||
endfunction
|
@ -0,0 +1,182 @@
|
||||
" install necessary Go tools
|
||||
if exists("g:go_loaded_install")
|
||||
finish
|
||||
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",
|
||||
\ "golang.org/x/tools/cmd/goimports",
|
||||
\ "code.google.com/p/rog-go/exp/cmd/godef",
|
||||
\ "golang.org/x/tools/cmd/oracle",
|
||||
\ "golang.org/x/tools/cmd/gorename",
|
||||
\ "github.com/golang/lint/golint",
|
||||
\ "github.com/kisielk/errcheck",
|
||||
\ "github.com/jstemmer/gotags",
|
||||
\ ]
|
||||
|
||||
" Commands
|
||||
command! GoErrCheck call go#errcheck#Run()
|
||||
|
||||
command! GoInstallBinaries call s:GoInstallBinaries(-1)
|
||||
command! GoUpdateBinaries call s:GoInstallBinaries(1)
|
||||
|
||||
" LineEnding returns the correct line ending, based on the current fileformat
|
||||
function! LineEnding()
|
||||
if &fileformat == 'dos'
|
||||
return "\r\n"
|
||||
elseif &fileformat == 'mac'
|
||||
return "\r"
|
||||
endif
|
||||
|
||||
return "\n"
|
||||
endfunction
|
||||
|
||||
" IsWin returns 1 if current OS is Windows or 0 otherwise
|
||||
function! IsWin()
|
||||
let win = ['win16', 'win32', 'win32unix', 'win64', 'win95']
|
||||
for w in win
|
||||
if (has(w))
|
||||
return 1
|
||||
endif
|
||||
endfor
|
||||
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
" PathSep returns the appropriate path separator based on OS.
|
||||
function! PathSep()
|
||||
if IsWin()
|
||||
return ";"
|
||||
endif
|
||||
|
||||
return ":"
|
||||
endfunction
|
||||
|
||||
" DefaultGoPath returns the default GOPATH.
|
||||
" If there is only one GOPATH it returns that, otherwise it returns the first one.
|
||||
function! DefaultGoPath()
|
||||
let go_paths = split($GOPATH, PathSep())
|
||||
|
||||
if len(go_paths) == 1
|
||||
return $GOPATH
|
||||
endif
|
||||
|
||||
return go_paths[0]
|
||||
endfunction
|
||||
|
||||
" GetBinPath returns the binary path of installed go tools
|
||||
function! GetBinPath()
|
||||
let bin_path = ""
|
||||
|
||||
" check if our global custom path is set, if not check if $GOBIN is set so
|
||||
" we can use it, otherwise use $GOPATH + '/bin'
|
||||
if exists("g:go_bin_path")
|
||||
let bin_path = g:go_bin_path
|
||||
elseif $GOBIN != ""
|
||||
let bin_path = $GOBIN
|
||||
elseif $GOPATH != ""
|
||||
let bin_path = expand(DefaultGoPath() . "/bin/")
|
||||
else
|
||||
" could not find anything
|
||||
endif
|
||||
|
||||
return bin_path
|
||||
endfunction
|
||||
|
||||
" GoInstallBinaries downloads and install all necessary binaries stated in the
|
||||
" packages variable. It uses by default $GOBIN or $GOPATH/bin as the binary
|
||||
" target install directory. GoInstallBinaries doesn't install binaries if they
|
||||
" exist, to update current binaries pass 1 to the argument.
|
||||
function! s:GoInstallBinaries(updateBinaries)
|
||||
if $GOPATH == ""
|
||||
echohl Error
|
||||
echomsg "vim.go: $GOPATH is not set"
|
||||
echohl None
|
||||
return
|
||||
endif
|
||||
|
||||
let err = s:CheckBinaries()
|
||||
if err != 0
|
||||
return
|
||||
endif
|
||||
|
||||
let go_bin_path = GetBinPath()
|
||||
|
||||
" change $GOBIN so go get can automatically install to it
|
||||
let $GOBIN = go_bin_path
|
||||
|
||||
" old_path is used to restore users own path
|
||||
let old_path = $PATH
|
||||
|
||||
" vim's executable path is looking in PATH so add our go_bin path to it
|
||||
let $PATH = $PATH . ":" .go_bin_path
|
||||
|
||||
for pkg in s:packages
|
||||
let basename = fnamemodify(pkg, ":t")
|
||||
let binname = "go_" . basename . "_bin"
|
||||
|
||||
let bin = basename
|
||||
if exists("g:{binname}")
|
||||
let bin = g:{binname}
|
||||
endif
|
||||
|
||||
if !executable(bin) || a:updateBinaries == 1
|
||||
if a:updateBinaries == 1
|
||||
echo "vim-go: Updating ". basename .". Reinstalling ". pkg . " to folder " . go_bin_path
|
||||
else
|
||||
echo "vim-go: ". basename ." not found. Installing ". pkg . " to folder " . go_bin_path
|
||||
endif
|
||||
|
||||
let out = system("go get -u -v ".shellescape(pkg))
|
||||
if v:shell_error
|
||||
echo "Error installing ". pkg . ": " . out
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
|
||||
" restore back!
|
||||
let $PATH = old_path
|
||||
endfunction
|
||||
|
||||
" CheckBinaries checks if the necessary binaries to install the Go tool
|
||||
" commands are available.
|
||||
function! s:CheckBinaries()
|
||||
if !executable('go')
|
||||
echohl Error | echomsg "vim-go: go executable not found." | echohl None
|
||||
return -1
|
||||
endif
|
||||
|
||||
if !executable('git')
|
||||
echohl Error | echomsg "vim-go: git executable not found." | echohl None
|
||||
return -1
|
||||
endif
|
||||
|
||||
if !executable('hg')
|
||||
echohl Error | echomsg "vim.go: hg (mercurial) executable not found." | echohl None
|
||||
return -1
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Autocommands
|
||||
" ============================================================================
|
||||
|
||||
augroup vim-go
|
||||
autocmd!
|
||||
|
||||
" GoInfo automatic update
|
||||
if get(g:, "go_auto_type_info", 0)
|
||||
autocmd CursorHold *.go nested call go#complete#Info()
|
||||
endif
|
||||
|
||||
" code formatting on save
|
||||
if get(g:, "go_fmt_autosave", 1)
|
||||
autocmd BufWritePre *.go call go#fmt#Format(-1)
|
||||
endif
|
||||
|
||||
augroup END
|
||||
|
||||
|
||||
" vim:ts=4:sw=4:et
|
@ -0,0 +1,78 @@
|
||||
#!/bin/bash -e
|
||||
#
|
||||
# Copyright 2012 The Go Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file.
|
||||
#
|
||||
# Tests for import.vim.
|
||||
|
||||
cd $(dirname $0)
|
||||
|
||||
cat > base.go <<EOF
|
||||
package test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"net"
|
||||
|
||||
"mycorp/foo"
|
||||
)
|
||||
EOF
|
||||
|
||||
fail=0
|
||||
|
||||
# usage: test_one command pattern
|
||||
# Pattern is a PCRE expression that will match across lines.
|
||||
test_one() {
|
||||
echo 2>&1 -n "$1: "
|
||||
vim -e -s -u /dev/null -U /dev/null --noplugin -c "source import.vim" \
|
||||
-c "$1" -c 'wq! test.go' base.go
|
||||
# ensure blank lines are treated correctly
|
||||
if ! gofmt test.go | cmp test.go -; then
|
||||
echo 2>&1 "gofmt conflict"
|
||||
gofmt test.go | diff -u test.go - | sed "s/^/ /" 2>&1
|
||||
fail=1
|
||||
return
|
||||
fi
|
||||
if ! [[ $(cat test.go) =~ $2 ]]; then
|
||||
echo 2>&1 "$2 did not match"
|
||||
cat test.go | sed "s/^/ /" 2>&1
|
||||
fail=1
|
||||
return
|
||||
fi
|
||||
echo 2>&1 "ok"
|
||||
}
|
||||
|
||||
# Tests for Import
|
||||
|
||||
test_one "Import baz" '"baz".*"bytes"'
|
||||
test_one "Import io/ioutil" '"io".*"io/ioutil".*"net"'
|
||||
test_one "Import myc" '"io".*"myc".*"net"' # prefix of a site prefix
|
||||
test_one "Import nat" '"io".*"nat".*"net"'
|
||||
test_one "Import net/http" '"net".*"net/http".*"mycorp/foo"'
|
||||
test_one "Import zoo" '"net".*"zoo".*"mycorp/foo"'
|
||||
test_one "Import mycorp/bar" '"net".*"mycorp/bar".*"mycorp/foo"'
|
||||
test_one "Import mycorp/goo" '"net".*"mycorp/foo".*"mycorp/goo"'
|
||||
|
||||
# Tests for Drop
|
||||
|
||||
cat > base.go <<EOF
|
||||
package test
|
||||
|
||||
import (
|
||||
"foo"
|
||||
|
||||
"something"
|
||||
"zoo"
|
||||
)
|
||||
EOF
|
||||
|
||||
test_one "Drop something" '\([^"]*"foo"[^"]*"zoo"[^"]*\)'
|
||||
|
||||
rm -f base.go test.go
|
||||
if [ $fail -gt 0 ]; then
|
||||
echo 2>&1 "FAIL"
|
||||
exit 1
|
||||
fi
|
||||
echo 2>&1 "PASS"
|
@ -0,0 +1,280 @@
|
||||
" Copyright 2009 The Go Authors. All rights reserved.
|
||||
" Use of this source code is governed by a BSD-style
|
||||
" license that can be found in the LICENSE file.
|
||||
"
|
||||
" go.vim: Vim syntax file for Go.
|
||||
"
|
||||
" Options:
|
||||
" There are some options for customizing the highlighting; the recommended
|
||||
" settings are the default values, but you can write:
|
||||
" let OPTION_NAME = 0
|
||||
" in your ~/.vimrc file to disable particular options. You can also write:
|
||||
" let OPTION_NAME = 1
|
||||
" to enable particular options.
|
||||
" At present, all options default to on, except highlight of:
|
||||
" functions, methods and structs.
|
||||
"
|
||||
" - go_highlight_array_whitespace_error
|
||||
" Highlights white space after "[]".
|
||||
" - go_highlight_chan_whitespace_error
|
||||
" Highlights white space around the communications operator that don't follow
|
||||
" the standard style.
|
||||
" - go_highlight_extra_types
|
||||
" Highlights commonly used library types (io.Reader, etc.).
|
||||
" - go_highlight_space_tab_error
|
||||
" Highlights instances of tabs following spaces.
|
||||
" - go_highlight_trailing_whitespace_error
|
||||
" Highlights trailing white space.
|
||||
|
||||
" Quit when a (custom) syntax file was already loaded
|
||||
if exists("b:current_syntax")
|
||||
finish
|
||||
endif
|
||||
|
||||
if !exists("g:go_highlight_array_whitespace_error")
|
||||
let g:go_highlight_array_whitespace_error = 1
|
||||
endif
|
||||
|
||||
if !exists("g:go_highlight_chan_whitespace_error")
|
||||
let g:go_highlight_chan_whitespace_error = 1
|
||||
endif
|
||||
|
||||
if !exists("g:go_highlight_extra_types")
|
||||
let g:go_highlight_extra_types = 1
|
||||
endif
|
||||
|
||||
if !exists("g:go_highlight_space_tab_error")
|
||||
let g:go_highlight_space_tab_error = 1
|
||||
endif
|
||||
|
||||
if !exists("g:go_highlight_trailing_whitespace_error")
|
||||
let g:go_highlight_trailing_whitespace_error = 1
|
||||
endif
|
||||
|
||||
if !exists("g:go_highlight_operators")
|
||||
let g:go_highlight_operators = 1
|
||||
endif
|
||||
|
||||
if !exists("g:go_highlight_functions")
|
||||
let g:go_highlight_functions = 0
|
||||
endif
|
||||
|
||||
if !exists("g:go_highlight_methods")
|
||||
let g:go_highlight_methods = 0
|
||||
endif
|
||||
|
||||
if !exists("g:go_highlight_structs")
|
||||
let g:go_highlight_structs = 0
|
||||
endif
|
||||
|
||||
syn case match
|
||||
|
||||
syn keyword goDirective package import
|
||||
syn keyword goDeclaration var const type
|
||||
syn keyword goDeclType struct interface
|
||||
|
||||
hi def link goDirective Statement
|
||||
hi def link goDeclaration Keyword
|
||||
hi def link goDeclType Keyword
|
||||
|
||||
" Keywords within functions
|
||||
syn keyword goStatement defer go goto return break continue fallthrough
|
||||
syn keyword goConditional if else switch select
|
||||
syn keyword goLabel case default
|
||||
syn keyword goRepeat for range
|
||||
|
||||
hi def link goStatement Statement
|
||||
hi def link goConditional Conditional
|
||||
hi def link goLabel Label
|
||||
hi def link goRepeat Repeat
|
||||
|
||||
" Predefined types
|
||||
syn keyword goType chan map bool string error
|
||||
syn keyword goSignedInts int int8 int16 int32 int64 rune
|
||||
syn keyword goUnsignedInts byte uint uint8 uint16 uint32 uint64 uintptr
|
||||
syn keyword goFloats float32 float64
|
||||
syn keyword goComplexes complex64 complex128
|
||||
|
||||
hi def link goType Type
|
||||
hi def link goSignedInts Type
|
||||
hi def link goUnsignedInts Type
|
||||
hi def link goFloats Type
|
||||
hi def link goComplexes Type
|
||||
|
||||
" Treat func specially: it's a declaration at the start of a line, but a type
|
||||
" elsewhere. Order matters here.
|
||||
syn match goDeclaration /\<func\>/
|
||||
|
||||
|
||||
" Predefined functions and values
|
||||
syn keyword goBuiltins append cap close complex copy delete imag len
|
||||
syn keyword goBuiltins make new panic print println real recover
|
||||
syn keyword goBoolean iota true false nil
|
||||
|
||||
hi def link goBuiltins Keyword
|
||||
hi def link goBoolean Boolean
|
||||
|
||||
" Comments; their contents
|
||||
syn keyword goTodo contained TODO FIXME XXX BUG
|
||||
syn cluster goCommentGroup contains=goTodo
|
||||
syn region goComment start="/\*" end="\*/" contains=@goCommentGroup,@Spell
|
||||
syn region goComment start="//" end="$" contains=@goCommentGroup,@Spell
|
||||
|
||||
hi def link goComment Comment
|
||||
hi def link goTodo Todo
|
||||
|
||||
" Go escapes
|
||||
syn match goEscapeOctal display contained "\\[0-7]\{3}"
|
||||
syn match goEscapeC display contained +\\[abfnrtv\\'"]+
|
||||
syn match goEscapeX display contained "\\x\x\{2}"
|
||||
syn match goEscapeU display contained "\\u\x\{4}"
|
||||
syn match goEscapeBigU display contained "\\U\x\{8}"
|
||||
syn match goEscapeError display contained +\\[^0-7xuUabfnrtv\\'"]+
|
||||
|
||||
hi def link goEscapeOctal goSpecialString
|
||||
hi def link goEscapeC goSpecialString
|
||||
hi def link goEscapeX goSpecialString
|
||||
hi def link goEscapeU goSpecialString
|
||||
hi def link goEscapeBigU goSpecialString
|
||||
hi def link goSpecialString Special
|
||||
hi def link goEscapeError Error
|
||||
|
||||
" Strings and their contents
|
||||
syn cluster goStringGroup contains=goEscapeOctal,goEscapeC,goEscapeX,goEscapeU,goEscapeBigU,goEscapeError
|
||||
syn region goString start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=@goStringGroup
|
||||
syn region goRawString start=+`+ end=+`+
|
||||
syn match goFormatSpecifier /%[#0\-\ \+\*]*[vTtbcdoqxXUeEfgGsp]/ contained containedin=goString
|
||||
|
||||
hi def link goString String
|
||||
hi def link goRawString String
|
||||
hi def link goFormatSpecifier goSpecialString
|
||||
|
||||
" Characters; their contents
|
||||
syn cluster goCharacterGroup contains=goEscapeOctal,goEscapeC,goEscapeX,goEscapeU,goEscapeBigU
|
||||
syn region goCharacter start=+'+ skip=+\\\\\|\\'+ end=+'+ contains=@goCharacterGroup
|
||||
|
||||
hi def link goCharacter Character
|
||||
|
||||
" Regions
|
||||
syn region goBlock start="{" end="}" transparent fold
|
||||
syn region goParen start='(' end=')' transparent
|
||||
|
||||
" Integers
|
||||
syn match goDecimalInt "\<\d\+\([Ee]\d\+\)\?\>"
|
||||
syn match goHexadecimalInt "\<0x\x\+\>"
|
||||
syn match goOctalInt "\<0\o\+\>"
|
||||
syn match goOctalError "\<0\o*[89]\d*\>"
|
||||
|
||||
hi def link goDecimalInt Integer
|
||||
hi def link goHexadecimalInt Integer
|
||||
hi def link goOctalInt Integer
|
||||
hi def link Integer Number
|
||||
|
||||
" Floating point
|
||||
syn match goFloat "\<\d\+\.\d*\([Ee][-+]\d\+\)\?\>"
|
||||
syn match goFloat "\<\.\d\+\([Ee][-+]\d\+\)\?\>"
|
||||
syn match goFloat "\<\d\+[Ee][-+]\d\+\>"
|
||||
|
||||
hi def link goFloat Float
|
||||
|
||||
" Imaginary literals
|
||||
syn match goImaginary "\<\d\+i\>"
|
||||
syn match goImaginary "\<\d\+\.\d*\([Ee][-+]\d\+\)\?i\>"
|
||||
syn match goImaginary "\<\.\d\+\([Ee][-+]\d\+\)\?i\>"
|
||||
syn match goImaginary "\<\d\+[Ee][-+]\d\+i\>"
|
||||
|
||||
hi def link goImaginary Number
|
||||
|
||||
" Spaces after "[]"
|
||||
if g:go_highlight_array_whitespace_error != 0
|
||||
syn match goSpaceError display "\(\[\]\)\@<=\s\+"
|
||||
endif
|
||||
|
||||
" Spacing errors around the 'chan' keyword
|
||||
if g:go_highlight_chan_whitespace_error != 0
|
||||
" receive-only annotation on chan type
|
||||
syn match goSpaceError display "\(<-\)\@<=\s\+\(chan\>\)\@="
|
||||
" send-only annotation on chan type
|
||||
syn match goSpaceError display "\(\<chan\)\@<=\s\+\(<-\)\@="
|
||||
" value-ignoring receives in a few contexts
|
||||
syn match goSpaceError display "\(\(^\|[={(,;]\)\s*<-\)\@<=\s\+"
|
||||
endif
|
||||
|
||||
" Extra types commonly seen
|
||||
if g:go_highlight_extra_types != 0
|
||||
syn match goExtraType /\<bytes\.\(Buffer\)\>/
|
||||
syn match goExtraType /\<io\.\(Reader\|Writer\|ReadWriter\|ReadWriteCloser\)\>/
|
||||
syn match goExtraType /\<reflect\.\(Kind\|Type\|Value\)\>/
|
||||
syn match goExtraType /\<unsafe\.Pointer\>/
|
||||
endif
|
||||
|
||||
" Space-tab error
|
||||
if g:go_highlight_space_tab_error != 0
|
||||
syn match goSpaceError display " \+\t"me=e-1
|
||||
endif
|
||||
|
||||
" Trailing white space error
|
||||
if g:go_highlight_trailing_whitespace_error != 0
|
||||
syn match goSpaceError display excludenl "\s\+$"
|
||||
endif
|
||||
|
||||
hi def link goExtraType Type
|
||||
hi def link goSpaceError Error
|
||||
|
||||
|
||||
|
||||
" included from: https://github.com/athom/more-colorful.vim/blob/master/after/syntax/go.vim
|
||||
"
|
||||
" Comments; their contents
|
||||
syn keyword goTodo contained NOTE
|
||||
hi def link goTodo Todo
|
||||
|
||||
|
||||
" Operators;
|
||||
if g:go_highlight_operators != 0
|
||||
syn match goOperator /:=/
|
||||
syn match goOperator />=/
|
||||
syn match goOperator /<=/
|
||||
syn match goOperator /==/
|
||||
syn match goOperator /!=/
|
||||
syn match goOperator /+=/
|
||||
syn match goOperator /-=/
|
||||
syn match goOperator /\s>\s/
|
||||
syn match goOperator /\s<\s/
|
||||
syn match goOperator /\s+\s/
|
||||
syn match goOperator /\s-\s/
|
||||
syn match goOperator /\s\*\s/
|
||||
syn match goOperator /\s\/\s/
|
||||
syn match goOperator /\s%\s/
|
||||
endif
|
||||
hi def link goOperator Operator
|
||||
|
||||
" Functions;
|
||||
if g:go_highlight_functions != 0
|
||||
syn match goFunction /\(func\s\+\)\@<=\w\+\((\)\@=/
|
||||
syn match goFunction /\()\s\+\)\@<=\w\+\((\)\@=/
|
||||
endif
|
||||
hi def link goFunction Function
|
||||
|
||||
" Methods;
|
||||
if g:go_highlight_methods != 0
|
||||
syn match goMethod /\(\.\)\@<=\w\+\((\)\@=/
|
||||
endif
|
||||
hi def link goMethod Type
|
||||
|
||||
" Structs;
|
||||
if g:go_highlight_structs != 0
|
||||
syn match goStruct /\(.\)\@<=\w\+\({\)\@=/
|
||||
syn match goStructDef /\(type\s\+\)\@<=\w\+\(\s\+struct\s\+{\)\@=/
|
||||
endif
|
||||
hi def link goStruct Function
|
||||
hi def link goStructDef Function
|
||||
|
||||
" Search backwards for a global declaration to start processing the syntax.
|
||||
"syn sync match goSync grouphere NONE /^\(const\|var\|type\|func\)\>/
|
||||
|
||||
" There's a bug in the implementation of grouphere. For now, use the
|
||||
" following as a more expensive/less precise workaround.
|
||||
syn sync minlines=500
|
||||
|
||||
let b:current_syntax = "go"
|
@ -0,0 +1,47 @@
|
||||
" Copyright 2011 The Go Authors. All rights reserved.
|
||||
" Use of this source code is governed by a BSD-style
|
||||
" license that can be found in the LICENSE file.
|
||||
|
||||
if exists("b:current_syntax")
|
||||
finish
|
||||
endif
|
||||
|
||||
syn case match
|
||||
|
||||
syn match godocTitle "^\([A-Z][A-Z ]*\)$"
|
||||
hi def link godocTitle Title
|
||||
|
||||
" Single Line Definitions
|
||||
syn match godocMethodRec /\i\+\ze)/ contained
|
||||
syn match godocMethodName /) \zs\i\+\ze(/ contained
|
||||
syn match godocMethod /^func \((\i\+ [^)]*)\) \i\+(/ contains=godocMethodRec,godocMethodName
|
||||
syn match godocFunction /^func \zs\i\+\ze(/
|
||||
|
||||
syn match godocType /^type \zs\i\+\ze.*/
|
||||
syn match godocVar /^var \zs\i\+\ze.*/
|
||||
syn match godocConst /^const \zs\i\+\ze.*/
|
||||
|
||||
hi def link godocMethodRec Type
|
||||
hi def link godocType Type
|
||||
hi def link godocMethodName Function
|
||||
hi def link godocFunction Function
|
||||
hi def link godocVar Identifier
|
||||
hi def link godocConst Identifier
|
||||
|
||||
" Definition Blocks
|
||||
syn region godocComment start="/\*" end="\*/" contained
|
||||
syn region godocComment start="//" end="$" contained
|
||||
syn match godocDefinition /^\s\+\i\+/ contained
|
||||
|
||||
syn region godocVarBlock start=/^var (/ end=/^)/ contains=godocComment,godocDefinition
|
||||
syn region godocConstBlock start=/^const (/ end=/^)/ contains=godocComment,godocDefinition
|
||||
syn region godocTypeBlock start=/^type \i\+ \(interface\|struct\) {/ end=/^}/ matchgroup=godocType contains=godocComment,godocType
|
||||
|
||||
hi def link godocComment Comment
|
||||
hi def link godocDefinition Identifier
|
||||
|
||||
syn sync minlines=500
|
||||
|
||||
let b:current_syntax = "godoc"
|
||||
|
||||
" vim:ts=4 sts=2 sw=2:
|
@ -0,0 +1,11 @@
|
||||
if exists("b:current_syntax")
|
||||
finish
|
||||
endif
|
||||
|
||||
let b:current_syntax = "vimgo"
|
||||
|
||||
syn match goInterface /^\S*/
|
||||
syn region goTitle start="\%1l" end=":"
|
||||
|
||||
hi def link goInterface Type
|
||||
hi def link goTitle Label
|
Loading…
Reference in New Issue