1
0
mirror of https://github.com/amix/vimrc synced 2025-07-31 17:55:00 +08:00

Updated plugins, also experimenting with a new font

The font is IBM Plex Mono: https://ibm.github.io/type/
This commit is contained in:
amix
2017-11-24 14:54:40 +01:00
parent 7fc202ec88
commit e9aac9794b
255 changed files with 2898 additions and 3752 deletions

View File

@ -1,9 +1,12 @@
Thanks for improving vim-go! Before you dive in please read the following:
1. Please read our
[Documentation](https://github.com/fatih/vim-go/blob/master/doc/vim-go.txt), it might
have answers for your problem
2. If you add a new feature please don't forget to update the documentation:
[Documentation](https://github.com/fatih/vim-go/blob/master/doc/vim-go.txt),
it might have a solution to your problem.
2. If you add a new feature then please don't forget to update the documentation:
[doc/vim-go.txt](https://github.com/fatih/vim-go/blob/master/doc/vim-go.txt).
3. If it's a breaking change or exceed +100 lines please open an issue first
and describe the changes you want to make.
3. If it's a breaking change or exceeds 100 lines of code then please open an
issue first and describe the changes you want to make.
4. See `:help go-development` for instructions on how to run and write tests. If
you add a new feature be sure you also include a test if feasible.

View File

@ -1,25 +1,22 @@
### Behavior
### What did you do? (required. The issue will be **closed** when not provided.)
Write here what's happening and what you're expecting instead of...
### Steps to reproduce:
### What did you expect to happen?
Please create a reproducible case of your problem. If this step is
not provided, the issue will be **closed**
Re produce it with a minimal `vimrc` with all plugins disabled and
only `vim-go` enabled:
### What happened instead?
1.
2.
3.
### Configuration
### Configuration (**MUST** fill this out):
Add here your current configuration and additional information that might be
useful, such as:
* Vim version (first two lines from `:version`):
* Go version (`go version`):
* Go environment (`go env`):
* `vimrc` you used to reproduce
* vim version:
* vim-go version:
* go version:
* `vimrc` you used to reproduce (use a *minimal* vimrc with other plugins disabled; do not link to a 2,000 line vimrc):

View File

@ -1,7 +1,2 @@
doc/tags
.DS_Store
# Test specific files
FAILED
test.log
scripts/vim-vimhelplint

View File

@ -1,21 +1,14 @@
language: go
env:
global:
- DEPS=$HOME/deps
- PATH=$DEPS/bin:$PATH
- PATCH="v8.0.0134"
install: |
git config --global user.email "you@example.com"
git config --global user.name "Your Name"
# check out if we can pre-compiled Vim releases somehow,
git clone --branch $PATCH --depth 1 https://github.com/vim/vim
cd vim
./configure --prefix=$DEPS --with-features=huge --disable-gui
make
make install
cd -
script: ./scripts/test.sh
notifications:
email: false
matrix:
include:
- env: SCRIPT=test VIM_VERSION=vim-7.4
- env: SCRIPT=test VIM_VERSION=vim-8.0
- env: SCRIPT=test VIM_VERSION=nvim
- env: SCRIPT=lint VIM_VERSION=vim-8.0
install:
- ./scripts/install-vim $VIM_VERSION
- pip install --user vim-vint
script:
- ./scripts/$SCRIPT $VIM_VERSION

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,28 @@
all: test
all: install test lint
install:
@echo "==> Installing Vims"
@./scripts/install-vim vim-7.4
@./scripts/install-vim vim-8.0
@./scripts/install-vim nvim
test:
@echo "==> Running tests"
@./scripts/test.sh
@./scripts/test vim-7.4
@./scripts/test vim-8.0
@./scripts/test nvim
.PHONY: all test
lint:
@echo "==> Running linting tools"
@./scripts/lint vim-8.0
docker:
@echo "==> Building/starting Docker container"
@./scripts/docker-test
clean:
@echo "==> Cleaning /tmp/vim-go-test"
@rm -rf /tmp/vim-go-test
.PHONY: all test install clean lint docker

View File

@ -8,64 +8,63 @@
This plugin adds Go language support for Vim, with the following main features:
* Build with `:GoBuild`, install with `:GoInstall` or test
with `:GoTest` (run single tests via `:GoTestFunc`)
* Show test coverage with `:GoCoverage` or in browser with `:GoCoverageBrowser`
* Goto definition with `:GoDef`
* Quick jump to declarations with `:GoDecls` or `:GoDeclsDir`
* Show documentation with `:GoDoc` inside or in browser with `:GoDocBrowser`
* Quickly execute your current file/files with `:GoRun`
* Advanced source analysis tools utilizing guru, such as `:GoImplements`,
`:GoCallees`, and `:GoReferrers`
* Change or display `GOPATH` with `:GoPath`
* Multiple 3rd linter support with `:GoMetaLinter`
* Renaming identifiers with `:GoRename`
* Share your code to [play.golang.org](http://play.golang.org) with `:GoPlay`
* Switch between `*.go` and `*_test.go` code with `:GoAlternate`
* Add/Remove tags on struct fields with `:GoAddTags`
* Add import paths via `:GoImport` or remove them with `:GoDrop`
* Custom vim text objects such as `a function (af)` or `inner function (if)`
* ... and many more! Please see [doc/vim-go.txt](doc/vim-go.txt) for more information.
* Compile your package with `:GoBuild`, install it with `:GoInstall` or test it
with `:GoTest`. Run a single tests with `:GoTestFunc`).
* Quickly execute your current file(s) with `:GoRun`.
* Improved syntax highlighting and folding.
* Completion support via `gocode`.
* `gofmt` or `goimports` on save keeps the cursor position and undo history.
* Go to symbol/declaration with `:GoDef`.
* Look up documentation with `:GoDoc` or `:GoDocBrowser`.
* Easily import packages via `:GoImport`, remove them via `:GoDrop`.
* Automatic `GOPATH` detection which works with `gb` and `godep`. Change or
display `GOPATH` with `:GoPath`.
* See which code is covered by tests with `:GoCoverage`.
* Add or remove tags on struct fields with `:GoAddTags` and `:GoRemoveTags`.
* Call `gometalinter` with `:GoMetaLinter` to invoke all possible linters
(`golint`, `vet`, `errcheck`, `deadcode`, etc.) and put the result in the
quickfix or location list.
* Lint your code with `:GoLint`, run your code through `:GoVet` to catch static
errors, or make sure errors are checked with `:GoErrCheck`.
* Advanced source analysis tools utilizing `guru`, such as `:GoImplements`,
`:GoCallees`, and `:GoReferrers`.
* Precise type-safe renaming of identifiers with `:GoRename`.
* ... and many more! Please see [doc/vim-go.txt](doc/vim-go.txt) for more
information.
## Install
Master branch is a **development** branch. Please use with caution.
I recommend to use the [**latest stable release**](https://github.com/fatih/vim-go/releases/latest)
The [**latest stable release**](https://github.com/fatih/vim-go/releases/latest) is the
recommended version to use. If you choose to use the master branch instead,
please do so with caution; it is a _development_ branch.
Vim-go follows the standard runtime path structure. Below are some helper lines
vim-go follows the standard runtime path structure. Below are some helper lines
for popular package managers:
* [Pathogen](https://github.com/tpope/vim-pathogen)
* `git clone https://github.com/fatih/vim-go.git ~/.vim/bundle/vim-go`
* [vim-plug](https://github.com/junegunn/vim-plug)
* `Plug 'fatih/vim-go'`
* [Vim packages](http://vimhelp.appspot.com/repeat.txt.html#packages)
* `git clone https://github.com/fatih/vim-go.git ~/.vim/pack/plugins/start/vim-go`
* [Vim 8 packages](http://vimhelp.appspot.com/repeat.txt.html#packages)
* `git clone https://github.com/fatih/vim-go.git ~/.vim/pack/plugins/start/vim-go`
* [Pathogen](https://github.com/tpope/vim-pathogen)
* `git clone https://github.com/fatih/vim-go.git ~/.vim/bundle/vim-go`
* [vim-plug](https://github.com/junegunn/vim-plug)
* `Plug 'fatih/vim-go'`
After installing, please install all necessary binaries. We have a handy
command for it:
You will also need to install all the necessary binaries. vim-go makes it easy
to install all of them by providing a command, `:GoInstallBinaries`, which will
`go get` all the required binaries.
```
:GoInstallBinaries
```
for more information please check out the [documentation](doc/vim-go.txt)
Check out the Install section in [the documentation](doc/vim-go.txt) for more
detailed instructions (`:help go-install`).
## Usage
Official documentation can be found under [doc/vim-go.txt](doc/vim-go.txt). You can display it from within Vim with:
The full documentation can be found at [doc/vim-go.txt](doc/vim-go.txt). You can
display it from within Vim with `:help vim-go`.
```
:help vim-go
```
Depending on your installation method, you may have to generate the plugin's
[`help tags`](http://vimhelp.appspot.com/helphelp.txt.html#%3Ahelptags)
manually (e.g. `:helptags ALL`).
Depending on your installation, you may have to generate the plugin's [help
tags](https://github.com/vim/vim/blob/v8.0.0711/runtime/doc/helphelp.txt#L206-L227)
manually (eg. `:helptags ALL`).
We also have an [official vim-go
tutorial](https://github.com/fatih/vim-go-tutorial).
We also have an [official vim-go tutorial](https://github.com/fatih/vim-go-tutorial).
## License

View File

@ -93,10 +93,6 @@ function! ctrlp#decls#enter() abort
return
endif
if exists("l:tmpname")
call delete(l:tmpname)
endif
let result = eval(out)
if type(result) != 4 || !has_key(result, 'decls')
return

View File

@ -9,20 +9,17 @@ endfunction
" default it tries to call simply 'go build', but it first tries to get all
" dependent files for the current folder and passes it to go build.
function! go#cmd#Build(bang, ...) abort
" expand all wildcards(i.e: '%' to the current file name)
let goargs = map(copy(a:000), "expand(v:val)")
" escape all shell arguments before we pass it to make
if !has('nvim')
let goargs = go#util#Shelllist(goargs, 1)
endif
" create our command arguments. go build discards any results when it
" Create our command arguments. go build discards any results when it
" compiles multiple packages. So we pass the `errors` package just as an
" placeholder with the current folder (indicated with '.'). We also pass -i
" that tries to install the dependencies, this has the side effect that it
" caches the build results, so every other build is faster.
let args = ["build"] + goargs + ["-i", ".", "errors"]
let args =
\ ["build"] +
\ map(copy(a:000), "expand(v:val)") +
\ ["-i", ".", "errors"]
" Vim async.
if go#util#has_job()
if get(g:, 'go_echo_command_info', 1)
call go#util#EchoProgress("building dispatched ...")
@ -31,50 +28,52 @@ function! go#cmd#Build(bang, ...) abort
call s:cmd_job({
\ 'cmd': ['go'] + args,
\ 'bang': a:bang,
\ 'for': 'GoBuild',
\})
return
" Nvim async.
elseif has('nvim')
if get(g:, 'go_echo_command_info', 1)
call go#util#EchoProgress("building dispatched ...")
endif
" if we have nvim, call it asynchronously and return early ;)
call go#jobcontrol#Spawn(a:bang, "build", args)
return
endif
call go#jobcontrol#Spawn(a:bang, "build", "GoBuild", args)
let old_gopath = $GOPATH
let $GOPATH = go#path#Detect()
let default_makeprg = &makeprg
let &makeprg = "go " . join(args, ' ')
let l:listtype = go#list#Type("quickfix")
" execute make inside the source folder so we can parse the errors
" correctly
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
let dir = getcwd()
try
execute cd . fnameescape(expand("%:p:h"))
if l:listtype == "locationlist"
silent! exe 'lmake!'
else
silent! exe 'make!'
endif
redraw!
finally
execute cd . fnameescape(dir)
endtry
let errors = go#list#Get(l:listtype)
call go#list#Window(l:listtype, len(errors))
if !empty(errors) && !a:bang
call go#list#JumpToFirst(l:listtype)
" Vim 7.4 without async
else
call go#util#EchoSuccess("[build] SUCCESS")
endif
let old_gopath = $GOPATH
let $GOPATH = go#path#Detect()
let default_makeprg = &makeprg
let &makeprg = "go " . join(go#util#Shelllist(args), ' ')
let &makeprg = default_makeprg
let $GOPATH = old_gopath
let l:listtype = go#list#Type("GoBuild")
" execute make inside the source folder so we can parse the errors
" correctly
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
let dir = getcwd()
try
execute cd . fnameescape(expand("%:p:h"))
if l:listtype == "locationlist"
silent! exe 'lmake!'
else
silent! exe 'make!'
endif
redraw!
finally
execute cd . fnameescape(dir)
endtry
let errors = go#list#Get(l:listtype)
call go#list#Window(l:listtype, len(errors))
if !empty(errors) && !a:bang
call go#list#JumpToFirst(l:listtype)
else
call go#util#EchoSuccess("[build] SUCCESS")
endif
let &makeprg = default_makeprg
let $GOPATH = old_gopath
endif
endfunction
@ -149,7 +148,7 @@ function! go#cmd#Run(bang, ...) abort
let &makeprg = "go run " . go#util#Shelljoin(map(copy(a:000), "expand(v:val)"), 1)
endif
let l:listtype = go#list#Type("quickfix")
let l:listtype = go#list#Type("GoRun")
if l:listtype == "locationlist"
exe 'lmake!'
@ -186,6 +185,7 @@ function! go#cmd#Install(bang, ...) abort
call s:cmd_job({
\ 'cmd': ['go', 'install'] + goargs,
\ 'bang': a:bang,
\ 'for': 'GoInstall',
\})
return
endif
@ -198,7 +198,7 @@ function! go#cmd#Install(bang, ...) abort
let goargs = go#util#Shelljoin(map(copy(a:000), "expand(v:val)"), 1)
let &makeprg = "go install " . goargs
let l:listtype = go#list#Type("quickfix")
let l:listtype = go#list#Type("GoInstall")
" execute make inside the source folder so we can parse the errors
" correctly
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
@ -243,7 +243,7 @@ function! go#cmd#Generate(bang, ...) abort
let &makeprg = "go generate " . goargs . ' ' . gofiles
endif
let l:listtype = go#list#Type("quickfix")
let l:listtype = go#list#Type("GoGenerate")
echon "vim-go: " | echohl Identifier | echon "generating ..."| echohl None
if l:listtype == "locationlist"

View File

@ -53,6 +53,7 @@ function! go#coverage#Buffer(bang, ...) abort
\ 'cmd': ['go', 'test', '-coverprofile', l:tmpname] + a:000,
\ 'custom_cb': function('s:coverage_callback', [l:tmpname]),
\ 'bang': a:bang,
\ 'for': 'GoTest',
\ })
return
endif
@ -94,9 +95,9 @@ function! go#coverage#Clear() abort
if exists("s:toggle") | let s:toggle = 0 | endif
" remove the autocmd we defined
if exists("#BufWinLeave#<buffer>")
autocmd! BufWinLeave <buffer>
endif
augroup vim-go-coverage
autocmd!
augroup end
endfunction
" Browser creates a new cover profile with 'go test -coverprofile' and opens
@ -108,6 +109,7 @@ function! go#coverage#Browser(bang, ...) abort
\ 'cmd': ['go', 'test', '-coverprofile', l:tmpname],
\ 'custom_cb': function('s:coverage_browser_callback', [l:tmpname]),
\ 'bang': a:bang,
\ 'for': 'GoTest',
\ })
return
endif
@ -256,7 +258,10 @@ function! go#coverage#overlay(file) abort
endfor
" clear the matches if we leave the buffer
autocmd BufWinLeave <buffer> call go#coverage#Clear()
augroup vim-go-coverage
autocmd!
autocmd BufWinLeave <buffer> call go#coverage#Clear()
augroup end
for m in matches
call matchaddpos(m.group, m.pos)

View File

@ -168,7 +168,7 @@ function! go#def#jump_to_declaration(out, mode, bin_name) abort
endif
" open the file and jump to line and column
exec cmd fnameescape(filename)
exec cmd fnameescape(fnamemodify(filename, ':.'))
endif
endif
call cursor(line, col)

View File

@ -1,32 +1,37 @@
func Test_jump_to_declaration_guru()
let file_name = "test-fixtures/def/jump.go"
let lnum = 5
let col = 6
func! Test_jump_to_declaration_guru() abort
try
let l:filename = 'def/jump.go'
let lnum = 5
let col = 6
let l:tmp = gotest#load_fixture(l:filename)
let out = printf("%s:%d:%d: defined here as func main", file_name, lnum, col)
let bin_name = "guru"
let guru_out = printf("%s:%d:%d: defined here as func main", filename, lnum, col)
call go#def#jump_to_declaration(guru_out, "", 'guru')
call go#def#jump_to_declaration(out, "", bin_name)
call assert_equal(file_name, bufname("%"))
call assert_equal(lnum, getcurpos()[1])
call assert_equal(col, getcurpos()[2])
call assert_equal(filename, bufname("%"))
call assert_equal(lnum, getcurpos()[1])
call assert_equal(col, getcurpos()[2])
finally
call delete(l:tmp, 'rf')
endtry
endfunc
func Test_jump_to_declaration_godef()
let file_name = "test-fixtures/def/jump.go"
let lnum = 5
let col = 6
func! Test_jump_to_declaration_godef() abort
try
let filename = 'def/jump.go'
let lnum = 5
let col = 6
let l:tmp = gotest#load_fixture(l:filename)
" note that the output of godef has two lines
let out = printf("%s:%d:%d\ndefined here as func main", file_name, lnum, col)
let bin_name = "godef"
let godef_out = printf("%s:%d:%d\ndefined here as func main", filename, lnum, col)
call go#def#jump_to_declaration(godef_out, "", 'godef')
call go#def#jump_to_declaration(out, "", bin_name)
call assert_equal(file_name, bufname("%"))
call assert_equal(lnum, getcurpos()[1])
call assert_equal(col, getcurpos()[2])
call assert_equal(filename, bufname("%"))
call assert_equal(lnum, getcurpos()[1])
call assert_equal(col, getcurpos()[2])
finally
call delete(l:tmp, 'rf')
endtry
endfunc
" vim: sw=2 ts=2 et

View File

@ -5,11 +5,7 @@
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 = ""
let g:go_doc_command = ["godoc"]
endif
function! go#doc#OpenBrowser(...) abort
@ -60,12 +56,11 @@ endfunction
function! go#doc#Open(newmode, mode, ...) abort
" With argument: run "godoc [arg]".
if len(a:000)
let bin_path = go#path#CheckBinPath('godoc')
if empty(bin_path)
if empty(go#path#CheckBinPath(g:go_doc_command[0]))
return
endif
let command = printf("%s %s", go#util#Shellescape(bin_path), join(a:000, ' '))
let command = printf("%s %s", go#util#Shelljoin(g:go_doc_command), join(a:000, ' '))
let out = go#util#System(command)
" Without argument: run gogetdoc on cursor position.
else
@ -85,6 +80,7 @@ endfunction
function! s:GodocView(newposition, position, content) abort
" reuse existing buffer window if it exists otherwise create a new one
let is_visible = bufexists(s:buf_nr) && bufwinnr(s:buf_nr) != -1
if !bufexists(s:buf_nr)
execute a:newposition
sil file `="[Godoc]"`
@ -96,20 +92,23 @@ function! s:GodocView(newposition, position, content) abort
execute bufwinnr(s:buf_nr) . 'wincmd w'
endif
if a:position == "split"
" cap window height to 20, but resize it for smaller contents
let max_height = get(g:, "go_doc_max_height", 20)
let content_height = len(split(a:content, "\n"))
if content_height > max_height
exe 'resize ' . max_height
" if window was not visible then resize it
if !is_visible
if a:position == "split"
" cap window height to 20, but resize it for smaller contents
let max_height = get(g:, "go_doc_max_height", 20)
let content_height = len(split(a:content, "\n"))
if content_height > max_height
exe 'resize ' . max_height
else
exe 'resize ' . content_height
endif
else
exe 'resize ' . content_height
" set a sane maximum width for vertical splits. In this case the minimum
" that fits the godoc for package http without extra linebreaks and line
" numbers on
exe 'vertical resize 84'
endif
else
" set a sane maximum width for vertical splits. In this case the minimum
" that fits the godoc for package http without extra linebreaks and line
" numbers on
exe 'vertical resize 84'
endif
setlocal filetype=godoc
@ -155,18 +154,8 @@ function! s:gogetdoc(json) abort
let command = join(cmd, " ")
if &modified
" gogetdoc supports the same archive format as guru for dealing with
" modified buffers.
" use the -modified flag
" write each archive entry on stdin as:
" filename followed by newline
" file size followed by newline
" file contents
let in = ""
let content = join(go#util#GetLines(), "\n")
let in = fname . "\n" . strlen(content) . "\n" . content
let command .= " -modified"
let out = go#util#System(command, in)
let out = go#util#System(command, go#util#archive())
else
let out = go#util#System(command)
endif

View File

@ -127,17 +127,23 @@ function! go#fmt#update_file(source, target)
let &fileformat = old_fileformat
let &syntax = &syntax
let l:listtype = go#list#Type("GoFmt")
" the title information was introduced with 7.4-2200
" https://github.com/vim/vim/commit/d823fa910cca43fec3c31c030ee908a14c272640
if !has('patch-7.4-2200')
return
if has('patch-7.4.2200')
" clean up previous list
if l:listtype == "quickfix"
let l:list_title = getqflist({'title': 1})
else
let l:list_title = getloclist(0, {'title': 1})
endif
else
" can't check the title, so assume that the list was for go fmt.
let l:list_title = {'title': 'Format'}
endif
" clean up previous location list
let l:list_title = getqflist({'title': 1})
if has_key(l:list_title, "title") && l:list_title['title'] == "Format"
let l:listtype = go#list#Type("quickfix")
call go#list#Clean(l:listtype)
call go#list#Window(l:listtype)
endif
@ -245,7 +251,7 @@ endfunction
" show_errors opens a location list and shows the given errors. If the given
" errors is empty, it closes the the location list
function! s:show_errors(errors) abort
let l:listtype = go#list#Type("quickfix")
let l:listtype = go#list#Type("GoFmt")
if !empty(a:errors)
call go#list#Populate(l:listtype, a:errors, 'Format')
echohl Error | echomsg "Gofmt returned error" | echohl None

View File

@ -1,4 +1,4 @@
func Test_run_fmt()
func! Test_run_fmt() abort
let actual_file = tempname()
call writefile(readfile("test-fixtures/fmt/hello.go"), actual_file)
@ -13,7 +13,7 @@ func Test_run_fmt()
call assert_equal(expected, actual)
endfunc
func Test_update_file()
func! Test_update_file() abort
let expected = join(readfile("test-fixtures/fmt/hello_golden.go"), "\n")
let source_file = tempname()
call writefile(readfile("test-fixtures/fmt/hello_golden.go"), source_file)
@ -30,7 +30,7 @@ func Test_update_file()
call assert_equal(expected, actual)
endfunc
func Test_goimports()
func! Test_goimports() abort
let $GOPATH = 'test-fixtures/fmt/'
let actual_file = tempname()
call writefile(readfile("test-fixtures/fmt/src/imports/goimports.go"), actual_file)
@ -45,3 +45,5 @@ func Test_goimports()
call assert_equal(expected, actual)
endfunc
" vim: sw=2 ts=2 et

View File

@ -34,8 +34,7 @@ function! s:guru_cmd(args) range abort
let filename = fnamemodify(expand("%"), ':p:gs?\\?/?')
if &modified
let content = join(go#util#GetLines(), "\n")
let result.stdin_content = filename . "\n" . strlen(content) . "\n" . content
let result.stdin_content = go#util#archive()
call add(cmd, "-modified")
endif
@ -112,7 +111,8 @@ function! s:sync_guru(args) abort
if !has_key(a:args, 'disable_progress')
if a:args.needs_scope
call go#util#EchoProgress("analysing with scope ". result.scope . " ...")
call go#util#EchoProgress("analysing with scope ". result.scope .
\ " (see ':help go-guru-scope' if this doesn't work)...")
elseif a:args.mode !=# 'what'
" the query might take time, let us give some feedback
call go#util#EchoProgress("analysing ...")
@ -150,7 +150,8 @@ function! s:async_guru(args) abort
if !has_key(a:args, 'disable_progress')
if a:args.needs_scope
call go#util#EchoProgress("analysing with scope ". result.scope . " ...")
call go#util#EchoProgress("analysing with scope " . result.scope .
\ " (see ':help go-guru-scope' if this doesn't work)...")
endif
endif
@ -159,9 +160,10 @@ function! s:async_guru(args) abort
call add(messages, a:msg)
endfunction
function! s:exit_cb(job, exitval) closure
let out = join(messages, "\n")
let status = {}
let exitval = 0
function! s:exit_cb(job, exitval) closure
let status = {
\ 'desc': 'last status',
\ 'type': statusline_type,
@ -169,21 +171,27 @@ function! s:async_guru(args) abort
\ }
if a:exitval
let exitval = a:exitval
let status.state = "failed"
endif
call go#statusline#Update(status_dir, status)
endfunction
function! s:close_cb(ch) closure
let out = join(messages, "\n")
if has_key(a:args, 'custom_parse')
call a:args.custom_parse(a:exitval, out)
call a:args.custom_parse(exitval, out)
else
call s:parse_guru_output(a:exitval, out, a:args.mode)
call s:parse_guru_output(exitval, out, a:args.mode)
endif
endfunction
let start_options = {
\ 'callback': funcref("s:callback"),
\ 'exit_cb': funcref("s:exit_cb"),
\ 'close_cb': funcref("s:close_cb"),
\ }
if has_key(result, 'stdin_content')
@ -521,28 +529,40 @@ function! s:same_ids_highlight(exit_val, output) abort
if get(g:, "go_auto_sameids", 0)
" re-apply SameIds at the current cursor position at the time the buffer
" is redisplayed: e.g. :edit, :GoRename, etc.
autocmd BufWinEnter <buffer> nested call go#guru#SameIds()
augroup vim-go-sameids
autocmd!
autocmd BufWinEnter <buffer> nested call go#guru#SameIds()
augroup end
endif
endfunction
" ClearSameIds returns 0 when it removes goSameId groups and non-zero if no
" goSameId groups are found.
function! go#guru#ClearSameIds() abort
let l:cleared = 0
let m = getmatches()
for item in m
if item['group'] == 'goSameId'
call matchdelete(item['id'])
let l:cleared = 1
endif
endfor
" remove the autocmds we defined
if exists("#BufWinEnter#<buffer>")
autocmd! BufWinEnter <buffer>
if !l:cleared
return 1
endif
" remove the autocmds we defined
augroup vim-go-sameids
autocmd!
augroup end
return 0
endfunction
function! go#guru#ToggleSameIds() abort
if len(getmatches()) != 0
call go#guru#ClearSameIds()
else
if go#guru#ClearSameIds() != 0
call go#guru#SameIds()
endif
endfunction
@ -583,11 +603,12 @@ function! s:parse_guru_output(exit_val, output, title) abort
let old_errorformat = &errorformat
let errformat = "%f:%l.%c-%[%^:]%#:\ %m,%f:%l:%c:\ %m"
call go#list#ParseFormat("locationlist", errformat, a:output, a:title)
let l:listtype = go#list#Type("_guru")
call go#list#ParseFormat(l:listtype, errformat, a:output, a:title)
let &errorformat = old_errorformat
let errors = go#list#Get("locationlist")
call go#list#Window("locationlist", len(errors))
let errors = go#list#Get(l:listtype)
call go#list#Window(l:listtype, len(errors))
endfun
function! go#guru#Scope(...) abort

View File

@ -6,11 +6,13 @@ function! go#impl#Impl(...) abort
let recv = ""
let iface = ""
let interactive = 0
let pos = getpos('.')
if a:0 == 0
" user didn't passed anything, just called ':GoImpl'
let receiveType = expand("<cword>")
let recv = printf("%s *%s", tolower(receiveType)[0], receiveType)
" Interactive mode if user didn't pass any arguments.
let recv = s:getReceiver()
let iface = input("vim-go: generating method stubs for interface: ")
redraw!
if empty(iface)
@ -20,8 +22,7 @@ function! go#impl#Impl(...) abort
elseif a:0 == 1
" we assume the user only passed the interface type,
" i.e: ':GoImpl io.Writer'
let receiveType = expand("<cword>")
let recv = printf("%s *%s", tolower(receiveType)[0], receiveType)
let recv = s:getReceiver()
let iface = a:1
elseif a:0 > 2
" user passed receiver and interface type both,
@ -33,20 +34,41 @@ function! go#impl#Impl(...) abort
return
endif
let result = go#util#System(join(go#util#Shelllist([binpath, recv, iface], ' ')))
if go#util#ShellError() != 0
call go#util#EchoError(result)
return
" Make sure we put the generated code *after* the struct.
if getline(".") =~ "struct "
normal! $%
endif
if result ==# ''
return
end
try
let dirname = fnameescape(expand('%:p:h'))
let result = go#util#System(join(go#util#Shelllist([binpath, '-dir', dirname, recv, iface], ' ')))
let result = substitute(result, "\n*$", "", "")
if go#util#ShellError() != 0
call go#util#EchoError(result)
return
endif
let pos = getpos('.')
put =''
put =result
call setpos('.', pos)
if result ==# ''
return
end
put =''
put =result
finally
call setpos('.', pos)
endtry
endfunction
function! s:getReceiver()
let receiveType = expand("<cword>")
if receiveType == "type"
normal! w
let receiveType = expand("<cword>")
elseif receiveType == "struct"
normal! ge
let receiveType = expand("<cword>")
endif
return printf("%s *%s", tolower(receiveType)[0], receiveType)
endfunction
if exists('*uniq')

View File

@ -10,12 +10,17 @@ function go#job#Spawn(args)
\ 'messages': [],
\ 'args': a:args.cmd,
\ 'bang': 0,
\ 'for': "_job",
\ }
if has_key(a:args, 'bang')
let cbs.bang = a:args.bang
endif
if has_key(a:args, 'for')
let cbs.for = a:args.for
endif
" add final callback to be called if async job is finished
" The signature should be in form: func(job, exit_status, messages)
if has_key(a:args, 'custom_cb')
@ -47,7 +52,7 @@ function go#job#Spawn(args)
call self.custom_cb(a:job, a:exitval, self.messages)
endif
let l:listtype = go#list#Type("quickfix")
let l:listtype = go#list#Type(self.for)
if a:exitval == 0
call go#list#Clean(l:listtype)
call go#list#Window(l:listtype)
@ -69,8 +74,7 @@ function go#job#Spawn(args)
if !len(errors)
" failed to parse errors, output the original content
call go#util#EchoError(join(self.messages, " "))
call go#util#EchoError(self.dir)
call go#util#EchoError(self.messages + [self.dir])
return
endif

View File

@ -9,11 +9,11 @@ let s:handlers = {}
" Spawn is a wrapper around s:spawn. It can be executed by other files and
" scripts if needed. Desc defines the description for printing the status
" during the job execution (useful for statusline integration).
function! go#jobcontrol#Spawn(bang, desc, args) abort
function! go#jobcontrol#Spawn(bang, desc, for, args) abort
" autowrite is not enabled for jobs
call go#cmd#autowrite()
let job = s:spawn(a:bang, a:desc, a:args)
let job = s:spawn(a:bang, a:desc, a:for, a:args)
return job.id
endfunction
@ -37,7 +37,7 @@ endfunction
" a job is started a reference will be stored inside s:jobs. spawn changes the
" GOPATH when g:go_autodetect_gopath is enabled. The job is started inside the
" current files folder.
function! s:spawn(bang, desc, args) abort
function! s:spawn(bang, desc, for, args) abort
let status_type = a:args[0]
let status_dir = expand('%:p:h')
let started_at = reltime()
@ -62,6 +62,7 @@ function! s:spawn(bang, desc, args) abort
\ 'status_type' : status_type,
\ 'status_dir' : status_dir,
\ 'started_at' : started_at,
\ 'for' : a:for,
\ }
" modify GOPATH if needed
@ -129,7 +130,7 @@ function! s:on_exit(job_id, exit_status, event) dict abort
call s:callback_handlers_on_exit(s:jobs[a:job_id], a:exit_status, std_combined)
let l:listtype = go#list#Type("quickfix")
let l:listtype = go#list#Type(self.for)
if a:exit_status == 0
call go#list#Clean(l:listtype)
call go#list#Window(l:listtype)

View File

@ -57,3 +57,5 @@ endfunction
function! s:chomp(string)
return substitute(a:string, '\n\+$', '', '')
endfunction
" vim: sw=2 ts=2 et

View File

@ -48,6 +48,13 @@ function! go#lint#Gometa(autosave, ...) abort
let cmd += ["--exclude=".exclude]
endfor
" gometalinter has a --tests flag to tell its linters whether to run
" against tests. While not all of its linters respect this flag, for those
" that do, it means if we don't pass --tests, the linter won't run against
" test files. One example of a linter that will not run against tests if
" we do not specify this flag is errcheck.
let cmd += ["--tests"]
" path
let cmd += [expand('%:p:h')]
else
@ -60,7 +67,7 @@ function! go#lint#Gometa(autosave, ...) abort
" For async mode (s:lint_job), we want to override the default deadline only
" if we have a deadline configured.
"
" For sync mode (go#tool#ExecuteInDir), always explicitly pass the 5 seconds
" For sync mode (go#util#System), always explicitly pass the 5 seconds
" deadline if there is no other deadline configured. If a deadline is
" configured, then use it.
@ -87,9 +94,9 @@ function! go#lint#Gometa(autosave, ...) abort
let meta_command = join(cmd, " ")
let out = go#tool#ExecuteInDir(meta_command)
let out = go#util#System(meta_command)
let l:listtype = "quickfix"
let l:listtype = go#list#Type("GoMetaLinter")
if go#util#ShellError() == 0
redraw | echo
call go#list#Clean(l:listtype)
@ -134,7 +141,7 @@ function! go#lint#Golint(...) abort
return
endif
let l:listtype = "quickfix"
let l:listtype = go#list#Type("GoLint")
call go#list#Parse(l:listtype, out)
let errors = go#list#Get(l:listtype)
call go#list#Window(l:listtype, len(errors))
@ -152,7 +159,7 @@ function! go#lint#Vet(bang, ...) abort
let out = go#util#System('go tool vet ' . go#util#Shelljoin(a:000))
endif
let l:listtype = "quickfix"
let l:listtype = go#list#Type("GoVet")
if go#util#ShellError() != 0
let errors = go#tool#ParseErrors(split(out, '\n'))
call go#list#Populate(l:listtype, errors, 'Vet')
@ -192,7 +199,7 @@ function! go#lint#Errcheck(...) abort
let command = go#util#Shellescape(bin_path) . ' -abspath ' . import_path
let out = go#tool#ExecuteInDir(command)
let l:listtype = "quickfix"
let l:listtype = go#list#Type("GoErrCheck")
if go#util#ShellError() != 0
let errformat = "%f:%l:%c:\ %m, %f:%l:%c\ %#%m"
@ -246,7 +253,7 @@ function s:lint_job(args)
" autowrite is not enabled for jobs
call go#cmd#autowrite()
let l:listtype = go#list#Type("quickfix")
let l:listtype = go#list#Type("GoMetaLinter")
let l:errformat = '%f:%l:%c:%t%*[^:]:\ %m,%f:%l::%t%*[^:]:\ %m'
function! s:callback(chan, msg) closure

View File

@ -2,13 +2,16 @@ if !exists("g:go_list_type")
let g:go_list_type = ""
endif
if !exists("g:go_list_type_commands")
let g:go_list_type_commands = {}
endif
" Window opens the list with the given height up to 10 lines maximum.
" Otherwise g:go_loclist_height is used.
" Otherwise g:go_loclist_height is used.
"
" If no or zero height is given it closes the window by default.
" If no or zero height is given it closes the window by default.
" To prevent this, set g:go_list_autoclose = 0
function! go#list#Window(listtype, ...) abort
let l:listtype = go#list#Type(a:listtype)
" we don't use lwindow to close the location list as we need also the
" ability to resize the window. So, we are going to use lopen and lclose
" for a better user experience. If the number of errors in a current
@ -17,7 +20,7 @@ function! go#list#Window(listtype, ...) abort
if !a:0 || a:1 == 0
let autoclose_window = get(g:, 'go_list_autoclose', 1)
if autoclose_window
if l:listtype == "locationlist"
if a:listtype == "locationlist"
lclose
else
cclose
@ -36,7 +39,7 @@ function! go#list#Window(listtype, ...) abort
endif
endif
if l:listtype == "locationlist"
if a:listtype == "locationlist"
exe 'lopen ' . height
else
exe 'copen ' . height
@ -44,20 +47,18 @@ function! go#list#Window(listtype, ...) abort
endfunction
" Get returns the current list of items from the location list
" Get returns the current items from the list
function! go#list#Get(listtype) abort
let l:listtype = go#list#Type(a:listtype)
if l:listtype == "locationlist"
if a:listtype == "locationlist"
return getloclist(0)
else
return getqflist()
endif
endfunction
" Populate populate the location list with the given items
" Populate populate the list with the given items
function! go#list#Populate(listtype, items, title) abort
let l:listtype = go#list#Type(a:listtype)
if l:listtype == "locationlist"
if a:listtype == "locationlist"
call setloclist(0, a:items, 'r')
" The last argument ({what}) is introduced with 7.4.2200:
@ -69,20 +70,15 @@ function! go#list#Populate(listtype, items, title) abort
endif
endfunction
function! go#list#PopulateWin(winnr, items) abort
call setloclist(a:winnr, a:items, 'r')
endfunction
" Parse parses the given items based on the specified errorformat and
" populates the location list.
" populates the list.
function! go#list#ParseFormat(listtype, errformat, items, title) abort
let l:listtype = go#list#Type(a:listtype)
" backup users errorformat, will be restored once we are finished
let old_errorformat = &errorformat
" parse and populate the location list
let &errorformat = a:errformat
if l:listtype == "locationlist"
if a:listtype == "locationlist"
lgetexpr a:items
if has("patch-7.4.2200") | call setloclist(0, [], 'a', {'title': a:title}) | endif
else
@ -95,10 +91,9 @@ function! go#list#ParseFormat(listtype, errformat, items, title) abort
endfunction
" Parse parses the given items based on the global errorformat and
" populates the location list.
" populates the list.
function! go#list#Parse(listtype, items) abort
let l:listtype = go#list#Type(a:listtype)
if l:listtype == "locationlist"
if a:listtype == "locationlist"
lgetexpr a:items
else
cgetexpr a:items
@ -107,8 +102,7 @@ endfunction
" JumpToFirst jumps to the first item in the location list
function! go#list#JumpToFirst(listtype) abort
let l:listtype = go#list#Type(a:listtype)
if l:listtype == "locationlist"
if a:listtype == "locationlist"
ll 1
else
cc 1
@ -117,22 +111,57 @@ endfunction
" Clean cleans the location list
function! go#list#Clean(listtype) abort
let l:listtype = go#list#Type(a:listtype)
if l:listtype == "locationlist"
if a:listtype == "locationlist"
lex []
else
cex []
endif
endfunction
function! go#list#Type(listtype) abort
function! s:listtype(listtype) abort
if g:go_list_type == "locationlist"
return "locationlist"
elseif g:go_list_type == "quickfix"
return "quickfix"
else
return a:listtype
endif
return a:listtype
endfunction
" s:default_list_type_commands is the defaults that will be used for each of
" the supported commands (see documentation for g:go_list_type_commands). When
" defining a default, quickfix should be used if the command operates on
" multiple files, while locationlist should be used if the command operates on a
" single file or buffer. Keys that begin with an underscore are not supported
" in g:go_list_type_commands.
let s:default_list_type_commands = {
\ "GoBuild": "quickfix",
\ "GoErrCheck": "quickfix",
\ "GoFmt": "locationlist",
\ "GoGenerate": "quickfix",
\ "GoInstall": "quickfix",
\ "GoLint": "quickfix",
\ "GoMetaLinter": "quickfix",
\ "GoModifyTags": "locationlist",
\ "GoRename": "quickfix",
\ "GoRun": "quickfix",
\ "GoTest": "quickfix",
\ "GoVet": "quickfix",
\ "_guru": "locationlist",
\ "_term": "locationlist",
\ "_job": "locationlist",
\ }
function! go#list#Type(for) abort
let l:listtype = s:listtype(get(s:default_list_type_commands, a:for))
if l:listtype == "0"
call go#util#EchoError(printf(
\ "unknown list type command value found ('%s'). Please open a bug report in the vim-go repo.",
\ a:for))
let l:listtype = "quickfix"
endif
return get(g:go_list_type_commands, a:for, l:listtype)
endfunction
" vim: sw=2 ts=2 et

View File

@ -80,6 +80,7 @@ function! go#package#FromPath(arg) abort
for dir in dirs
if len(dir) && match(path, dir) == 0
let workspace = dir
break
endif
endfor
@ -87,10 +88,12 @@ function! go#package#FromPath(arg) abort
return -1
endif
let path = substitute(path, '/*$', '', '')
let workspace = substitute(workspace . '/src/', '/+', '', '')
if isdirectory(path)
return substitute(path, workspace . 'src/', '', '')
return substitute(path, workspace, '', '')
else
return substitute(substitute(path, workspace . 'src/', '', ''),
return substitute(substitute(path, workspace, '', ''),
\ '/' . fnamemodify(path, ':t'), '', '')
endif
endfunction

View File

@ -73,7 +73,7 @@ function! go#path#Detect() abort
let gopath = go#path#Default()
" don't lookup for godeps if autodetect is disabled.
if !get(g:, "go_autodetect_gopath", 1)
if !get(g:, "go_autodetect_gopath", 0)
return gopath
endif
@ -179,7 +179,6 @@ function! go#path#CheckBinPath(binpath) abort
" just get the basename
let basename = fnamemodify(binpath, ":t")
if !executable(basename)
call go#util#EchoError(printf("could not find '%s'. Run :GoInstallBinaries to fix it", basename))
" restore back!

View File

@ -70,24 +70,4 @@ function! s:get_visual_selection() abort
return join(lines, "\n")
endfunction
" following two functions are from: https://github.com/mattn/gist-vim
" thanks @mattn
function! s:get_browser_command() abort
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') || go#util#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: sw=2 ts=2 et

View File

@ -2,17 +2,25 @@ if !exists("g:go_gorename_bin")
let g:go_gorename_bin = "gorename"
endif
if !exists("g:go_gorename_prefill")
let g:go_gorename_prefill = 1
endif
" Set the default value. A value of "1" is a shortcut for this, for
" compatibility reasons.
function! s:default() abort
if !exists("g:go_gorename_prefill") || g:go_gorename_prefill == 1
let g:go_gorename_prefill = 'expand("<cword>") =~# "^[A-Z]"' .
\ '? go#util#pascalcase(expand("<cword>"))' .
\ ': go#util#camelcase(expand("<cword>"))'
endif
endfunction
call s:default()
function! go#rename#Rename(bang, ...) abort
call s:default()
let to_identifier = ""
if a:0 == 0
let from = expand("<cword>")
let ask = printf("vim-go: rename '%s' to: ", from)
if g:go_gorename_prefill
let to_identifier = input(ask, from)
let ask = printf("vim-go: rename '%s' to: ", expand("<cword>"))
if g:go_gorename_prefill != ''
let to_identifier = input(ask, eval(g:go_gorename_prefill))
else
let to_identifier = input(ask)
endif
@ -24,7 +32,7 @@ function! go#rename#Rename(bang, ...) abort
let to_identifier = a:1
endif
"return with a warning if the bin doesn't exist
" return with a warning if the bin doesn't exist
let bin_path = go#path#CheckBinPath(g:go_gorename_bin)
if empty(bin_path)
return
@ -117,7 +125,7 @@ function s:parse_errors(exit_val, bang, out)
silent! checktime
let &autoread = current_autoread
let l:listtype = "quickfix"
let l:listtype = go#list#Type("GoRename")
if a:exit_val != 0
call go#util#EchoError("FAILED")
let errors = go#tool#ParseErrors(a:out)
@ -127,7 +135,7 @@ function s:parse_errors(exit_val, bang, out)
call go#list#JumpToFirst(l:listtype)
elseif empty(errors)
" failed to parse errors, output the original content
call go#util#EchoError(join(a:out, ""))
call go#util#EchoError(a:out)
endif
return
@ -146,4 +154,13 @@ function s:parse_errors(exit_val, bang, out)
silent execute ":e"
endfunction
" Commandline completion: original, unexported camelCase, and exported
" CamelCase.
function! go#rename#Complete(lead, cmdline, cursor)
let l:word = expand('<cword>')
return filter(uniq(sort(
\ [l:word, go#util#camelcase(l:word), go#util#pascalcase(l:word)])),
\ 'strpart(v:val, 0, len(a:lead)) == a:lead')
endfunction
" vim: sw=2 ts=2 et

View File

@ -95,12 +95,12 @@ func s:write_out(out) abort
if has_key(result, 'errors')
let l:winnr = winnr()
let l:listtype = go#list#Type("quickfix")
let l:listtype = go#list#Type("GoModifyTags")
call go#list#ParseFormat(l:listtype, "%f:%l:%c:%m", result['errors'], "gomodifytags")
call go#list#Window(l:listtype, len(result['errors']))
"prevent jumping to quickfix list
exe l:winnr . "wincmd w"
exe l:winnr . "wincmd w"
endif
endfunc
@ -210,3 +210,5 @@ func s:create_cmd(args) abort
return {'cmd': cmd}
endfunc
" vim: sw=2 ts=2 et

View File

@ -1,28 +1,22 @@
func Test_add_tags()
let input_file = tempname()
call writefile(readfile("test-fixtures/tags/add_all_input.go"), input_file)
let expected = join(readfile("test-fixtures/tags/add_all_golden.go"), "\n")
" run for offset 40, which is inside the struct
call go#tags#run(0, 0, 40, "add", input_file, 1)
let actual = join(readfile(input_file), "\n")
call assert_equal(expected, actual)
func! Test_add_tags() abort
try
let l:tmp = gotest#load_fixture('tags/add_all_input.go')
silent call go#tags#run(0, 0, 40, "add", bufname(''), 1)
call gotest#assert_fixture('tags/add_all_golden.go')
finally
call delete(l:tmp, 'rf')
endtry
endfunc
func Test_remove_tags()
let input_file = tempname()
call writefile(readfile("test-fixtures/tags/remove_all_input.go"), input_file)
let expected = join(readfile("test-fixtures/tags/remove_all_golden.go"), "\n")
" run for offset 40, which is inside the struct
call go#tags#run(0, 0, 40, "remove", input_file, 1)
let actual = join(readfile(input_file), "\n")
call assert_equal(expected, actual)
func! Test_remove_tags() abort
try
let l:tmp = gotest#load_fixture('tags/remove_all_input.go')
silent call go#tags#run(0, 0, 40, "remove", bufname(''), 1)
call gotest#assert_fixture('tags/remove_all_golden.go')
finally
call delete(l:tmp, 'rf')
endtry
endfunc
" vim:ts=2:sts=2:sw=2:et

View File

@ -77,6 +77,7 @@ function! go#term#newmode(bang, cmd, mode) abort
call jobresize(id, width, height)
let s:jobs[id] = job
stopinsert
return id
endfunction
@ -104,7 +105,7 @@ function! s:on_exit(job_id, exit_status, event) dict abort
endif
let job = s:jobs[a:job_id]
let l:listtype = "locationlist"
let l:listtype = go#list#Type("_term")
" usually there is always output so never branch into this clause
if empty(job.stdout)

View File

@ -6,9 +6,13 @@ function! go#test#Test(bang, compile, ...) abort
" don't run the test, only compile it. Useful to capture and fix errors.
if a:compile
" we're going to tell to run a test function that doesn't exist. This
" triggers a build of the test file itself but no tests will run.
call extend(args, ["-run", "499EE4A2-5C85-4D35-98FC-7377CD87F263"])
let testfile = tempname() . ".vim-go.test"
call extend(args, ["-c", "-o", testfile])
endif
if exists('g:go_build_tags')
let tags = get(g:, 'go_build_tags')
call extend(args, ["-tags", tags])
endif
if a:0
@ -33,9 +37,9 @@ function! go#test#Test(bang, compile, ...) abort
if get(g:, 'go_echo_command_info', 1)
if a:compile
echon "vim-go: " | echohl Identifier | echon "compiling tests ..." | echohl None
call go#util#EchoProgress("compiling tests ...")
else
echon "vim-go: " | echohl Identifier | echon "testing ..." | echohl None
call go#util#EchoProgress("testing...")
endif
endif
@ -57,7 +61,7 @@ function! go#test#Test(bang, compile, ...) abort
if get(g:, 'go_term_enabled', 0)
let id = go#term#new(a:bang, ["go"] + args)
else
let id = go#jobcontrol#Spawn(a:bang, "test", args)
let id = go#jobcontrol#Spawn(a:bang, "test", "GoTest", args)
endif
return id
@ -69,7 +73,7 @@ function! go#test#Test(bang, compile, ...) abort
let command = "go " . join(args, ' ')
let out = go#tool#ExecuteInDir(command)
let l:listtype = "quickfix"
let l:listtype = go#list#Type("GoTest")
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
let dir = getcwd()
@ -87,15 +91,15 @@ function! go#test#Test(bang, compile, ...) abort
" failed to parse errors, output the original content
call go#util#EchoError(out)
endif
echon "vim-go: " | echohl ErrorMsg | echon "[test] FAIL" | echohl None
call go#util#EchoError("[test] FAIL")
else
call go#list#Clean(l:listtype)
call go#list#Window(l:listtype)
if a:compile
echon "vim-go: " | echohl Function | echon "[test] SUCCESS" | echohl None
call go#util#EchoSuccess("[test] SUCCESS")
else
echon "vim-go: " | echohl Function | echon "[test] PASS" | echohl None
call go#util#EchoSuccess("[test] PASS")
endif
endif
execute cd . fnameescape(dir)
@ -172,12 +176,12 @@ function s:test_job(args) abort
if get(g:, 'go_echo_command_info', 1)
if a:exitval == 0
if a:args.compile_test
call go#util#EchoSuccess("SUCCESS")
call go#util#EchoSuccess("[test] SUCCESS")
else
call go#util#EchoSuccess("PASS")
call go#util#EchoSuccess("[test] PASS")
endif
else
call go#util#EchoError("FAILED")
call go#util#EchoError("[test] FAIL")
endif
endif
@ -188,7 +192,7 @@ function s:test_job(args) abort
call go#statusline#Update(status_dir, status)
let l:listtype = go#list#Type("quickfix")
let l:listtype = go#list#Type("GoTest")
if a:exitval == 0
call go#list#Clean(l:listtype)
call go#list#Window(l:listtype)
@ -222,9 +226,9 @@ endfunction
" show_errors parses the given list of lines of a 'go test' output and returns
" a quickfix compatible list of errors. It's intended to be used only for go
" test output.
" test output.
function! s:show_errors(args, exit_val, messages) abort
let l:listtype = go#list#Type("quickfix")
let l:listtype = go#list#Type("GoTest")
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
try
@ -237,7 +241,7 @@ function! s:show_errors(args, exit_val, messages) abort
if !len(errors)
" failed to parse errors, output the original content
call go#util#EchoError(join(a:messages, " "))
call go#util#EchoError(a:messages)
call go#util#EchoError(a:args.dir)
return
endif
@ -253,28 +257,85 @@ endfunction
function! s:parse_errors(lines) abort
let errors = []
let paniced = 0 " signals whether all remaining lines should be included in errors.
let test = ''
" NOTE(arslan): once we get JSON output everything will be easier :)
" https://github.com/golang/go/issues/2981
for line in a:lines
let fatalerrors = matchlist(line, '^\(fatal error:.*\)$')
let tokens = matchlist(line, '^\s*\(.\{-}\.go\):\(\d\+\):\s*\(.*\)')
let fatalerrors = matchlist(line, '^\(\(fatal error\|panic\):.*\)$')
if !empty(fatalerrors)
call add(errors, {"text": fatalerrors[1]})
elseif !empty(tokens)
let paniced = 1
call add(errors, {"text": line})
continue
endif
if !paniced
" Matches failure lines. These lines always have zero or more leading spaces followed by '-- FAIL: ', following by the test name followed by a space the duration of the test in parentheses
" e.g.:
" '--- FAIL: TestSomething (0.00s)'
let failure = matchlist(line, '^ *--- FAIL: \(.*\) (.*)$')
if get(g:, 'go_test_prepend_name', 0)
if !empty(failure)
let test = failure[1] . ': '
continue
endif
endif
endif
let tokens = []
if paniced
" Matches lines in stacktraces produced by panic. The lines always have
" one or more leading tabs, followed by the path to the file. The file
" path is followed by a colon and then the line number within the file
" where the panic occurred. After that there's a space and hexadecimal
" number.
"
" e.g.:
" '\t/usr/local/go/src/time.go:1313 +0x5d'
let tokens = matchlist(line, '^\t\+\(.\{-}\.go\):\(\d\+\) \(+0x.*\)')
else
" matches lines produced by `go test`. All lines produced by `go test`
" that we're interested in start with zero or more spaces (increasing
" depth of subtests is represented by a similar increase in the number
" of spaces at the start of output lines. Top level tests start with
" zero leading spaces). Lines that indicate test status (e.g. RUN, FAIL,
" PASS) start after the spaces. Lines that indicate test failure
" location or test log message location (e.g. "testing.T".Log) begin
" with the appropriate number of spaces for the current test level,
" followed by a tab, a filename , a colon, the line number, another
" colon, a space, and the failure or log message.
"
" e.g.:
" '\ttime_test.go:30: Likely problem: the time zone files have not been installed.'
let tokens = matchlist(line, '^ *\t\+\(.\{-}\.go\):\(\d\+\):\s*\(.*\)')
endif
if !empty(tokens) " Check whether the line may refer to a file.
" strip endlines of form ^M
let out = substitute(tokens[3], '\r$', '', '')
let file = fnamemodify(tokens[1], ':p')
" Preserve the line when the filename is not readable. This is an
" unusual case, but possible; any test that produces lines that match
" the pattern used in the matchlist assigned to tokens is a potential
" source of this condition. For instance, github.com/golang/mock/gomock
" will sometimes produce lines that satisfy this condition.
if !filereadable(file)
call add(errors, {"text": test . line})
continue
endif
call add(errors, {
\ "filename" : fnamemodify(tokens[1], ':p'),
\ "filename" : file,
\ "lnum" : tokens[2],
\ "text" : out,
\ "text" : test . out,
\ })
elseif paniced
call add(errors, {"text": line})
elseif !empty(errors)
" Preserve indented lines.
" This comes up especially with multi-line test output.
if match(line, '^\s') >= 0
" Preserve indented lines. This comes up especially with multi-line test output.
if match(line, '^ *\t\+') >= 0
call add(errors, {"text": line})
endif
endif
@ -284,4 +345,3 @@ function! s:parse_errors(lines) abort
endfunction
" vim: sw=2 ts=2 et
"

View File

@ -162,6 +162,18 @@ function! go#tool#FilterValids(items) abort
endfunction
function! go#tool#ExecuteInDir(cmd) abort
" Verify that the directory actually exists. If the directory does not
" exist, then assume that the a:cmd should not be executed. Callers expect
" to check v:shell_error (via go#util#ShellError()), so execute a command
" that will return an error as if a:cmd was run and exited with an error.
" This helps avoid errors when working with plugins that use virtual files
" that don't actually exist on the file system (e.g. vim-fugitive's
" GitDiff).
if !isdirectory(expand("%:p:h"))
let [out, err] = go#util#Exec(["false"])
return ''
endif
let old_gopath = $GOPATH
let old_goroot = $GOROOT
let $GOPATH = go#path#Detect()
@ -194,7 +206,6 @@ function! go#tool#Exists(importpath) abort
return 0
endfunction
" following two functions are from: https://github.com/mattn/gist-vim
" thanks @mattn
function! s:get_browser_command() abort
@ -202,12 +213,14 @@ function! s:get_browser_command() abort
if go_play_browser_command == ''
if go#util#IsWin()
let go_play_browser_command = '!start rundll32 url.dll,FileProtocolHandler %URL%'
elseif has('mac') || has('macunix') || has('gui_macvim') || go#util#System('uname') =~? '^darwin'
elseif go#util#IsMac()
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% &'
elseif executable('chromium')
let go_play_browser_command = 'chromium %URL% &'
else
let go_play_browser_command = ''
endif

View File

@ -43,6 +43,14 @@ function! go#util#IsWin() abort
return 0
endfunction
" IsMac returns 1 if current OS is macOS or 0 otherwise.
function! go#util#IsMac() abort
return has('mac') ||
\ has('macunix') ||
\ has('gui_macvim') ||
\ go#util#System('uname') =~? '^darwin'
endfunction
" Checks if using:
" 1) Windows system,
" 2) And has cygpath executable,
@ -110,25 +118,22 @@ function! go#util#osarch() abort
return go#util#env("goos") . '_' . go#util#env("goarch")
endfunction
" System runs a shell command. If possible, it will temporary set
" the shell to /bin/sh for Unix-like systems providing a Bourne
" POSIX like environment.
function! go#util#System(str, ...) abort
" Run a shell command.
"
" It will temporary set the shell to /bin/sh for Unix-like systems if possible,
" so that we always use a standard POSIX-compatible Bourne shell (and not e.g.
" csh, fish, etc.) See #988 and #1276.
function! s:system(cmd, ...) abort
" Preserve original shell and shellredir values
let l:shell = &shell
let l:shellredir = &shellredir
" Use a Bourne POSIX like shell. Some parts of vim-go expect
" commands to be executed using bourne semantics #988 and #1276.
" Alter shellredir to match bourne. Especially important if login shell
" is set to any of the csh or zsh family #1276.
if !go#util#IsWin() && executable('/bin/sh')
set shell=/bin/sh shellredir=>%s\ 2>&1
endif
try
let l:output = call('system', [a:str] + a:000)
return l:output
return call('system', [a:cmd] + a:000)
finally
" Restore original values
let &shell = l:shell
@ -136,6 +141,31 @@ function! go#util#System(str, ...) abort
endtry
endfunction
" System runs a shell command "str". Every arguments after "str" is passed to
" stdin.
function! go#util#System(str, ...) abort
return call('s:system', [a:str] + a:000)
endfunction
" Exec runs a shell command "cmd", which must be a list, one argument per item.
" Every list entry will be automatically shell-escaped
" Every other argument is passed to stdin.
function! go#util#Exec(cmd, ...) abort
if len(a:cmd) == 0
call go#util#EchoError("go#util#Exec() called with empty a:cmd")
return
endif
" CheckBinPath will show a warning for us.
let l:bin = go#path#CheckBinPath(a:cmd[0])
if empty(l:bin)
return ["", 1]
endif
let l:out = call('s:system', [go#util#Shelljoin([l:bin] + a:cmd[1:])] + a:000)
return [l:out, go#util#ShellError()]
endfunction
function! go#util#ShellError() abort
return v:shell_error
endfunction
@ -242,50 +272,71 @@ endfunction
" snakecase converts a string to snake case. i.e: FooBar -> foo_bar
" Copied from tpope/vim-abolish
function! go#util#snakecase(word) abort
let word = substitute(a:word,'::','/','g')
let word = substitute(word,'\(\u\+\)\(\u\l\)','\1_\2','g')
let word = substitute(word,'\(\l\|\d\)\(\u\)','\1_\2','g')
let word = substitute(word,'[.-]','_','g')
let word = substitute(a:word, '::', '/', 'g')
let word = substitute(word, '\(\u\+\)\(\u\l\)', '\1_\2', 'g')
let word = substitute(word, '\(\l\|\d\)\(\u\)', '\1_\2', 'g')
let word = substitute(word, '[.-]', '_', 'g')
let word = tolower(word)
return word
endfunction
" camelcase converts a string to camel case. i.e: FooBar -> fooBar
" Copied from tpope/vim-abolish
" camelcase converts a string to camel case. e.g. FooBar or foo_bar will become
" fooBar.
" Copied from tpope/vim-abolish.
function! go#util#camelcase(word) abort
let word = substitute(a:word, '-', '_', 'g')
if word !~# '_' && word =~# '\l'
return substitute(word,'^.','\l&','')
return substitute(word, '^.', '\l&', '')
else
return substitute(word,'\C\(_\)\=\(.\)','\=submatch(1)==""?tolower(submatch(2)) : toupper(submatch(2))','g')
return substitute(word, '\C\(_\)\=\(.\)', '\=submatch(1)==""?tolower(submatch(2)) : toupper(submatch(2))','g')
endif
endfunction
" TODO(arslan): I couldn't parameterize the highlight types. Check if we can
" simplify the following functions
" pascalcase converts a string to 'PascalCase'. e.g. fooBar or foo_bar will
" become FooBar.
function! go#util#pascalcase(word) abort
let word = go#util#camelcase(a:word)
return toupper(word[0]) . word[1:]
endfunction
" Echo a message to the screen and highlight it with the group in a:hi.
"
" NOTE(arslan): echon doesn't work well with redraw, thus echo doesn't print
" even though we order it. However echom seems to be work fine.
" The message can be a list or string; every line with be :echomsg'd separately.
function! s:echo(msg, hi)
let l:msg = []
if type(a:msg) != type([])
let l:msg = split(a:msg, "\n")
else
let l:msg = a:msg
endif
" Tabs display as ^I or <09>, so manually expand them.
let l:msg = map(l:msg, 'substitute(v:val, "\t", " ", "")')
exe 'echohl ' . a:hi
for line in l:msg
echom "vim-go: " . line
endfor
echohl None
endfunction
function! go#util#EchoSuccess(msg)
redraw | echohl Function | echom "vim-go: " . a:msg | echohl None
call s:echo(a:msg, 'Function')
endfunction
function! go#util#EchoError(msg)
redraw | echohl ErrorMsg | echom "vim-go: " . a:msg | echohl None
call s:echo(a:msg, 'ErrorMsg')
endfunction
function! go#util#EchoWarning(msg)
redraw | echohl WarningMsg | echom "vim-go: " . a:msg | echohl None
call s:echo(a:msg, 'WarningMsg')
endfunction
function! go#util#EchoProgress(msg)
redraw | echohl Identifier | echom "vim-go: " . a:msg | echohl None
call s:echo(a:msg, 'Identifier')
endfunction
function! go#util#EchoInfo(msg)
redraw | echohl Debug | echom "vim-go: " . a:msg | echohl None
call s:echo(a:msg, 'Debug')
endfunction
" Get all lines in the buffer as a a list.
function! go#util#GetLines()
let buf = getline(1, '$')
if &encoding != 'utf-8'
@ -299,4 +350,49 @@ function! go#util#GetLines()
return buf
endfunction
" Convert the current buffer to the "archive" format of
" golang.org/x/tools/go/buildutil:
" https://godoc.org/golang.org/x/tools/go/buildutil#ParseOverlayArchive
"
" > The archive consists of a series of files. Each file consists of a name, a
" > decimal file size and the file contents, separated by newlinews. No newline
" > follows after the file contents.
function! go#util#archive()
let l:buffer = join(go#util#GetLines(), "\n")
return expand("%:p:gs!\\!/!") . "\n" . strlen(l:buffer) . "\n" . l:buffer
endfunction
" Make a named temporary directory which starts with "prefix".
"
" Unfortunately Vim's tempname() is not portable enough across various systems;
" see: https://github.com/mattn/vim-go/pull/3#discussion_r138084911
function! go#util#tempdir(prefix) abort
" See :help tempfile
if go#util#IsWin()
let l:dirs = [$TMP, $TEMP, 'c:\tmp', 'c:\temp']
else
let l:dirs = [$TMPDIR, '/tmp', './', $HOME]
endif
let l:dir = ''
for l:d in dirs
if !empty(l:d) && filewritable(l:d) == 2
let l:dir = l:d
break
endif
endfor
if l:dir == ''
echoerr 'Unable to find directory to store temporary directory in'
return
endif
" Not great randomness, but "good enough" for our purpose here.
let l:rnd = sha256(printf('%s%s', localtime(), fnamemodify(bufname(''), ":p")))
let l:tmp = printf("%s/%s%s", l:dir, a:prefix, l:rnd)
call mkdir(l:tmp, 'p', 0700)
return l:tmp
endfunction
" vim: sw=2 ts=2 et

View File

@ -4,10 +4,10 @@
"
" compiler/go.vim: Vim compiler file for Go.
if exists("current_compiler")
if exists("g:current_compiler")
finish
endif
let current_compiler = "go"
let g:current_compiler = "go"
if exists(":CompilerSet") != 2
command -nargs=* CompilerSet setlocal <args>

View File

@ -21,70 +21,73 @@ CONTENTS *go-contents*
5. Text Objects.................................|go-text-objects|
6. Functions....................................|go-functions|
7. Settings.....................................|go-settings|
8. FAQ/Troubleshooting..........................|go-troubleshooting|
9. Development..................................|go-development|
10. Donation.....................................|go-donation|
11. Credits......................................|go-credits|
8. Syntax highlighting..........................|go-syntax|
9. FAQ/Troubleshooting..........................|go-troubleshooting|
10. Development..................................|go-development|
11. Donation.....................................|go-donation|
12. 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.
Go (golang) support for Vim. vim-go comes with sensible predefined settings
(e.g. automatic `gofmt` on save), has autocomplete, snippet support, improved
syntax highlighting, go toolchain commands, etc. It is highly customizable,
and individual features can be toggled easily. vim-go leverages a number of
tools developed by the Go community to provide a seamless Vim experience.
* Improved Syntax highlighting with items such as Functions, Operators,
Methods.
* Auto completion support via `gocode`.
* Better `gofmt` on save, which 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 `:GoImport` or plug it into autosave.
* Compile your package with `:GoBuild`, install them with `:GoInstall` or
test them with `:GoTest` (also supports running single tests with
`:GoTestFunc`).
* Quickly execute your current file/files with `:GoRun`.
* Automatic `GOPATH` detection based on the directory structure (e.g. `gb`
projects, `godep` vendored projects).
* Change or display `GOPATH` with `:GoPath`.
* Create a coverage profile and display annotated source code in to see
which functions are covered with `:GoCoverage`.
* Call `gometalinter` with `:GoMetaLinter`, which invokes all possible
linters (golint, vet, errcheck, deadcode, etc..) and shows the
warnings/errors.
* Lint your code with `:GoLint`.
* Run your code through `:GoVet` to catch static errors.
* Advanced source analysis tools utilizing guru, such as `:GoImplements`,
`:GoCallees`, and `:GoReferrers`.
* Precise type-safe renaming of identifiers with `:GoRename`.
* List all source files and dependencies.
* Unchecked error checking with `:GoErrCheck`.
* Compile your package with |:GoBuild|, install it with |:GoInstall| or
test it with |:GoTest|. Run a single tests with |:GoTestFunc|).
* Quickly execute your current file(s) with |:GoRun|.
* Improved syntax highlighting and folding.
* Completion support via `gocode`.
* `gofmt` or `goimports` on save keeps the cursor position and undo history.
* Go to symbol/declaration with |:GoDef|.
* Look up documentation with |:GoDoc| or |:GoDocBrowser|.
* Easily import packages via |:GoImport|, remove them via |:GoDrop|.
* Automatic `GOPATH` detection which works with `gb` and `godep`. Change or
display `GOPATH` with |:GoPath|.
* See which code is covered by tests with |:GoCoverage|.
* Add or remove tags on struct fields with |:GoAddTags| and |:GoRemoveTags|.
* Call `gometalinter` with |:GoMetaLinter| to invoke all possible linters
(`golint`, `vet`, `errcheck`, `deadcode`, etc.) and put the result in the
quickfix or location list.
* Lint your code with |:GoLint|, run your code through |:GoVet| to catch
static errors, or make sure errors are checked with |:GoErrCheck|.
* Advanced source analysis tools utilizing `guru`, such as |:GoImplements|,
|:GoCallees|, and |:GoReferrers|.
* Precise type-safe renaming of identifiers with |:GoRename|.
* Integrated and improved snippets, supporting `ultisnips` or `neosnippet`.
* Share your current code to [play.golang.org](http://play.golang.org) with
`:GoPlay`
* On-the-fly type information about the word under the cursor. Plug it into
your custom Vim function.
* Go asm formatting on save.
* Tagbar support to show tags of the source code in a sidebar with `gotags`.
* Custom vim text objects such as `a function` or `inner function`.
* A async launcher for the go command is implemented for neovim, fully async
* Share your current code to play.golang.org with |:GoPlay|.
* On-the-fly information about the word under the cursor. Plug it into your
custom Vim function.
* Text objects such as "a function" (|go-af|) or "inner function" (|go-if|).
* Most commands are run asynchronous in Neovim and Vim 8. Fully async
building and testing.
* Integrated with the neovim terminal, launch `:GoRun` and other go commands
in their own new terminal.
* Alternate between implementation and test code with `:GoAlternate`.
* Integrated with the Neovim terminal, launch |:GoRun| and other Go commands
in a terminal buffer.
* Switch between `file.go` and `file_test.go` code with |:GoAlternate|.
* Supports integration with the Tagbar and ctrlp.vim plugins.
* ...and more...
==============================================================================
INSTALL *go-install*
Vim-go follows the standard runtime path structure, so I highly recommend to
use a common and well known plugin manager to install vim-go. Do not use
vim-go with other Go plugins. For Pathogen just clone the repo, for other
plugin managers add the appropriate lines and execute the plugin's install
command.
The latest stable release, https://github.com/fatih/vim-go/releases/latest, is
the recommended version to use. If you choose to use the master branch
instead, please do so with caution; it is a _development_ branch.
vim-go follows the standard runtime path structure and should work with any of
the major plugin managers.
For Pathogen or Vim |packages|, just clone the repo. For other plugin managers
you may also need to add the lines to your vimrc to execute the plugin
manager's install command.
* Vim 8 |packages|
>
git clone https://github.com/fatih/vim-go.git \
~/.vim/pack/plugins/start/vim-go
* https://github.com/tpope/vim-pathogen >
@ -101,37 +104,51 @@ command.
* https://github.com/gmarik/vundle >
Plugin 'fatih/vim-go'
* Vim |packages|
>
git clone https://github.com/fatih/vim-go.git \
~/.vim/pack/plugins/start/vim-go
<
* Manual >
* Manual (not recommended) >
Copy all of the files into your `~/.vim` directory
<
You will also need to install all the necessary binaries. vim-go makes it easy
to install all of them by providing a command, |:GoInstallBinaries|, to
`go get` all the required binaries. The binaries will be installed to $GOBIN
or $GOPATH/bin (default: $HOME/go/bin). It requires `git`.
Please be sure all necessary binaries are installed (such as `gocode`,
`godef`, `goimports`, etc.). You can easily install them with the included
|:GoInstallBinaries| command. If you invoke it, all necessary binaries will be
automatically downloaded and installed to your `$GOBIN` environment (if not
set it will use `$GOPATH/bin`). It requires `git` for fetching the individual
Go packages.
Depending on your installation method, you may have to generate the plugin's
|:helptags| manually (e.g. `:helptags ALL`).
Autocompletion is enabled by default via 'omnifunc', which you can trigger
with |i_CTRL-X_CTRL-O| (`<C-x><C-o>`).
Supported Go plugins~ *vim-go-plugins*
The following plugins are supported for use with vim-go:
* Real-time completion (Vim):
https://github.com/Shougo/neocomplete.vim
* Real-time completion (Neovim):
https://github.com/Shougo/deoplete.nvim and
https://github.com/zchee/deoplete-go
* Display source code navigation in a sidebar:
https://github.com/majutsushi/tagbar
* Snippets:
https://github.com/Shougo/neosnippet.vim or
https://github.com/SirVer/ultisnips
* Autocompletion is enabled by default via `<C-x><C-o>`, to get real-time
completion (completion by type) install:
https://github.com/Shougo/neocomplete.vim for Vim or
https://github.com/Shougo/deoplete.nvim and
https://github.com/zchee/deoplete-go for Neovim
* To get displayed source code tag informations on a sidebar install
https://github.com/majutsushi/tagbar.
* For snippet feature install:
https://github.com/Shougo/neosnippet.vim or
https://github.com/SirVer/ultisnips.
* For a better documentation viewer check out:
https://github.com/garyburd/go-explorer
* Integration with `delve` (Neovim only):
https://github.com/jodosha/vim-godebug
* Interactive |:GoDecls| and |:GoDeclsDir|:
https://github.com/ctrlpvim/ctrlp.vim or
https://github.com/junegunn/fzf.vim or
https://github.com/Shougo/unite.vim
==============================================================================
COMMANDS *go-commands*
@ -455,18 +472,24 @@ CTRL-t
Show dependencies for the current package.
*:GoInstallBinaries*
:GoInstallBinaries
:GoInstallBinaries [binaries]
Download and Install all necessary Go tool binaries such as `godef`,
`goimports`, `gocode`, etc. under `g:go_bin_path`. Set
|'g:go_get_update'| to disable updating dependencies.
Download and install all necessary Go tool binaries such as `godef`,
`goimports`, `gocode`, etc. under |'g:go_bin_path'|. If [binaries] is
supplied, then only the specified binaries will be installed. The default
is to install everything.
Set |'g:go_get_update'| to disable updating dependencies.
*:GoUpdateBinaries*
:GoUpdateBinaries
:GoUpdateBinaries [binaries]
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.
Download and update previously installed Go tool binaries such as `godef`,
`goimports`, `gocode`, etc. under |'g:go_bin_path'|. If [binaries] is
supplied, then only the specified binaries will be updated. The default is
to update everything.
Set |'g:go_get_update'| to disable updating dependencies.
*:GoImplements*
:GoImplements
@ -507,6 +530,8 @@ CTRL-t
Under the hood, the patterns are all joined to a comma-separated list and
passed to `guru`'s `-scope` flag.
Also see |go-guru-scope|.
*:GoCallees*
:GoCallees
@ -541,13 +566,13 @@ CTRL-t
*:GoFreevars*
:GoFreevars
Enumerates the free variables of the selection. Free variables is a
Enumerates the free variables of the selection. "Free variables" is a
technical term meaning the set of variables that are referenced but not
defined within the selection, or loosely speaking, its inputs.
This information is useful if youre considering whether to refactor the
This information is useful when considering whether to refactor the
selection into a function of its own, as the free variables would be the
necessary parameters of that function. Its also useful when you want to
necessary parameters of that function. It's also useful when you want to
understand what the inputs are to a complex block of code even if you
dont plan to change it.
@ -654,19 +679,35 @@ CTRL-t
*:GoDecls*
:GoDecls [file]
Only enabled if `ctrlp.vim` is installed. If run shows all function and
type declarations for the current file. If [file] is non empty it parses
the given file.
Show all function and type declarations for the current file. If
[file] is non empty it parses the given file.
Requires `ctrlp.vim` or `fzf`; it will autodetect the plugin if installed,
but you can use |'g:go_decls_mode'| to force using one or the other.
By default `type` and `func` declarations are shown. This can be changed
via |'g:go_decls_includes'|.
via |'g:go_decls_includes'|. Also see |unite-decls|.
*:GoDeclsDir*
:GoDeclsDir [dir]
Only enabled if `ctrlp.vim` is installed. If run shows all function and
type declarations for the current directory. If [dir] is given it parses
the given directory.
Show all function and type declarations for the current directory. If
[dir] is given it parses the given directory.
*unite-decls*
:Unite decls[:file or dir]
Only enabled if `unite.vim` is installed. Show declarations for all
functions and types on the current file or directory. If [:file or dir]
is non empty, it parses the given one.
>
" show declarations on the parent directory of the current file
:Unite decls
" show declarations on the file
:Unite decls:foo/bar.go
" show declarations on the directory
:Unite decls:foo
<
*:GoImpl*
:GoImpl [receiver] [interface]
@ -676,7 +717,7 @@ CTRL-t
receiver and the interface needs to be specified. Example usages:
>
:GoImpl f *Foo io.Writer
:GoImpl T io.ReadWriteCloser
:GoImpl t Type io.ReadWriteCloser
<
*:GoAddTags*
:[range]GoAddTags [key],[option] [key1],[option] ...
@ -766,12 +807,31 @@ CTRL-t
Surname: "Smith",
}
<
*:GoFillStruct*
:GoFillStruct
Use `fillstruct` to fill a struct literal with default values. Existing
values (if any) are preserved. The cursor must be on the struct you wish
to fill.
For example:
>
addr := net.Address{Name: "Ford Prefect"}
<
Becomes:
>
addr := net.Address{
Name: "Ford Prefect",
Email: "",
}
<
==============================================================================
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` for the current package, create
a mapping for the `(go-run)`: >
For example, to create a mapping that calls `go run` for the current package,
create a mapping for the `(go-run)`: >
au FileType go nmap <leader>r <Plug>(go-run)
@ -1031,6 +1091,14 @@ into the statusline. This function is also used for |'g:go_auto_type_info'|.
==============================================================================
SETTINGS *go-settings*
*'g:go_test_prepend_name'*
Prepend the name of the failed test to each test message generated by a failed
test. By default it is disabled.
>
let g:go_test_prepend_name = 0
<
*'g:go_test_timeout'*
Use this option to change the test timeout of |:GoTest|. By default it is
@ -1040,10 +1108,14 @@ set to 10 seconds . >
<
*'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. >
Browser to use for |:GoPlay| or |:GoDocBrowser|. The url must be added with
`%URL%`, and it's advisable to include `&` to make sure the shell returns. For
example:
>
let g:go_play_browser_command = 'firefox-developer %URL% &'
<
By default it tries to find it automatically for the current OS. >
let g:go_play_browser_command = ''
<
@ -1117,11 +1189,11 @@ used >
Use this option to add additional options to the |'g:go_fmt_command'|. It's
value type can be either a string or a dictionary. This is due backwards
compatibility. The string version will be removed in the future so please use
the dictionary version. Default is empty.
the dictionary version. Default is empty.
>
let g:go_fmt_options = ''
or
or
let g:go_fmt_options = {}
<
@ -1134,7 +1206,7 @@ The dictionary version allows you to define options for multiple binaries:
<
*'g:go_fmt_fail_silently'*
Use this option to disable showing a quickfix list when |'g:go_fmt_command'|
Use this option to disable showing a location list when |'g:go_fmt_command'|
fails. By default the location list is shown. >
let g:go_fmt_fail_silently = 0
@ -1190,17 +1262,11 @@ mappings of |:GoDef|. By default it's disabled. >
<
*'g:go_doc_command'*
Use this option to define which tool is used to godoc. By default `godoc` is
used >
Command to use for |:GoDoc|; only used when invoked with a package name. The
`gogetdoc` command is always used when |:GoDoc| is used on the identifier
under the cursor (i.e. without argument or from |K|). >
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 = ''
let g:go_doc_command = ["godoc"]
< *'g:go_bin_path'*
@ -1230,8 +1296,11 @@ Use this option to define the scope of the analysis to be passed for guru
related commands, such as |:GoImplements|, |:GoCallers|, etc. You can change
it on-the-fly with |:GoGuruScope|. The input should be a a list of package
pattern. An example input might be:
`["github.com/fatih/color","github.com/fatih/structs"]` By default it's not
set, so the relevant commands defaults are being used.
`["github.com/fatih/color","github.com/fatih/structs"]`
Also see |go-guru-scope|.
By default it's not set, so the relevant commands defaults are being used.
>
let g:go_guru_scope = []
<
@ -1243,94 +1312,6 @@ setting. A more useful way is to use |:GoBuildTags| to dynamically change or
remove build tags. By default it's not set.
>
let g:go_build_tags = ''
<
*'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 doesn'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_types'*
Highlights struct and interface names. By default it's disabled. >
let g:go_highlight_types = 0
<
*'g:go_highlight_fields'*
Highlights field names. By default it's disabled. >
let g:go_highlight_fields = 0
<
*'g:go_highlight_build_constraints'*
Highlights build constraints. By default it's disabled. >
let g:go_highlight_build_constraints = 0
<
*'g:go_highlight_generate_tags'*
Highlights go:generate directives. By default it's disabled. >
let g:go_highlight_generate_tags = 0
<
*'g:go_highlight_string_spellcheck'*
Use this option to highlight spelling errors in strings when |spell| is
also enabled. By default it's enabled. >
let g:go_highlight_string_spellcheck = 1
<
*'g:go_highlight_format_strings'*
Use this option to highlight printf-style operators inside string literals.
By default it's enabled. >
let g:go_highlight_format_strings = 1
<
*'g:go_autodetect_gopath'*
@ -1339,9 +1320,9 @@ the tool `godep` which has his own dependencies via the `Godeps` folder. What
this means is that all tools are now working with the newly modified GOPATH.
So |:GoDef| for example jumps to the source inside the `Godeps` (vendored)
source. Currently `godep` and `gb` is supported, in the near future more tool
supports will be added. By default it's enabled. >
supports will be added. By default it's disabled. >
let g:go_autodetect_gopath = 1
let g:go_autodetect_gopath = 0
<
*'g:go_textobj_enabled'*
@ -1418,18 +1399,38 @@ explicitly overrides this behavior. For standard Vim behavior, set it to 10.
*'g:go_list_type'*
Specifies the type of list to use for command outputs (such as errors from
builds, results from static analysis commands, etc...). The default value
(empty) will use the appropriate kind of list for the command that was called.
Supported values are "", "quickfix", and "locationlist". >
builds, results from static analysis commands, etc...). The list type for
specific commands can be overridden with |'g:go_list_type_commands'|. The
default value (empty) will use the appropriate kind of list for the command
that was called. Supported values are "", "quickfix", and "locationlist".
>
let g:go_list_type = ""
<
*'g:go_list_type_commands'*
Specifies the type of list to use for command outputs (such as errors from
builds, results from static analysis commands, etc...). When an expected key
is not present in the dictionary, |'g:go_list_type'| will be used instead.
Supported keys are "GoBuild", "GoErrCheck", "GoFmt", "GoInstall", "GoLint",
"GoMetaLinter", "GoModifyTags" (used for both :GoAddTags and :GoRemoveTags),
"GoRename", "GoRun", and "GoTest". Supported values for each command are
"quickfix" and "locationlist".
>
let g:go_list_type_commands = {}
<
As an example, the following settings will change all list types to
`locationlist` except for `:GoBuild` where `quickfix` is used:
>
let g:go_list_type = "locationlist"
let g:go_list_type_commands = {"GoBuild": "quickfix"}
<
*'g:go_list_autoclose'*
Specifies whether the quickfix/location list should be closed automatically
in the absence of errors. The default value is 1.
If you prefer to keep a long running error window open, you can disable
If you prefer to keep a long running error window open, you can disable
this by setting the value to 0.
>
let g:go_list_autoclose = 1
@ -1479,10 +1480,15 @@ By default it is set to edit.
<
*'g:go_gorename_prefill'*
Specifies whether |:GoRename| prefills the new identifier name with the
word under the cursor. By default it is enabled.
Expression to prefill the new identifier when using |:GoRename| without any
arguments. Use an empty string if you don't want to prefill anything. By
default it converts the identifier to camel case but preserves the
capitalisation of the first letter to ensure that the exported state stays the
same.
>
let g:go_gorename_prefill = 1
let g:go_gorename_prefill = 'expand("<cword>") =~# "^[A-Z]"' .
\ '? go#util#pascalcase(expand("<cword>"))' .
\ ': go#util#camelcase(expand("<cword>"))'
<
*'g:go_gocode_autobuild'*
@ -1559,11 +1565,20 @@ By default the template file specified by |'g:go_template_file'| is used.
<
*'g:go_decls_includes'*
Only useful if `ctrlp.vim` is installed. This sets which declarations to show
for |:GoDecls|. It is a Comma delimited list Possible options are:
Only useful if `ctrlp.vim`, `unite.vim` or `fzf` are installed. This sets
which declarations to show for |:GoDecls| (`ctrp.vim`) and |unite-decls|
(`unite.vim`). It is a Comma delimited list Possible options are:
{func,type}. The default is: >
let g:go_decls_includes = 'func,type'
<
*'g:go_decls_mode'*
Define the tool to be used for |:GoDecls|. Valid options are `ctrlp.vim`,
`fzf`, or an empty string; in which case it will try to autodetect either
`ctrlp.vim` or `fzf`.
>
let g:go_decls_mode = ''
<
*'g:go_echo_command_info'*
@ -1612,19 +1627,32 @@ By default "snakecase" is used. Current values are: ["snakecase",
>
let g:go_addtags_transform = 'snakecase'
<
*'g:go_fold_enable'*
==============================================================================
SYNTAX HIGHLIGHTING *ft-go-syntax* *go-syntax*
vim-go comes with an enhanced version of Vim's Go syntax highlighting. It
comes with a number of features, most of which are disabled by default.
The recommended settings are the default values. If you're experiencing
slowdowns in Go files and you enabled some of these options then try disabling
them; some can be resource intensive.
*'g:go_fold_enable'*
Control syntax-based folding which takes effect when 'foldmethod' is set to
`syntax`.
You can enable specific fold regions by setting an array. Possible values are:
- "block" `{` .. `}` blocks.
- "import" `import` block.
- "varconst" `var` and `const` blocks.
block `{` .. `}` blocks.
import `import` block.
varconst `var` and `const` blocks.
package_comment The package comment.
comment Any comment that is not the package comment.
By default they're all enabled:
By default all except "comment" are enabled:
>
let g:go_fold_enable = ['block', 'import', 'varconst']
let g:go_fold_enable = ['block', 'import', 'varconst', 'package_comment']
<
Enable folding of only imports:
>
@ -1634,27 +1662,118 @@ Disable everything (same as not setting 'foldmethod' to `syntax`):
>
let g:go_fold_enable = []
<
*'g:go_highlight_array_whitespace_error'*
Highlight white space after `[]`. >
let g:go_highlight_array_whitespace_error = 0
<
*'g:go_highlight_chan_whitespace_error'*
Highlight white space around the receive operator (`<-`) that doesn't follow
the standard style. >
let g:go_highlight_chan_whitespace_error = 0
<
*'g:go_highlight_extra_types'*
Highlight commonly used library types (`io.Reader`, etc.). >
let g:go_highlight_extra_types = 0
<
*'g:go_highlight_space_tab_error'*
Highlight instances of tabs following spaces. >
let g:go_highlight_space_tab_error = 0
<
*'g:go_highlight_trailing_whitespace_error'*
Highlight trailing white space. >
let g:go_highlight_trailing_whitespace_error = 0
<
*'g:go_highlight_operators'*
Highlight operators such as `:=` , `==`, `-=`, etc.
>
let g:go_highlight_operators = 0
<
*'g:go_highlight_functions'*
Highlight function names.
>
let g:go_highlight_functions = 0
<
*'g:go_highlight_methods'*
Highlight method names.
>
let g:go_highlight_methods = 0
<
*'g:go_highlight_types'*
Highlight struct and interface names.
>
let g:go_highlight_types = 0
<
*'g:go_highlight_fields'*
Highlight struct field names.
>
let g:go_highlight_fields = 0
<
*'g:go_highlight_build_constraints'*
Highlights build constraints.
>
let g:go_highlight_build_constraints = 0
<
*'g:go_highlight_generate_tags'*
Highlight go:generate directives.
>
let g:go_highlight_generate_tags = 0
<
*'g:go_highlight_string_spellcheck'*
Highlight spelling errors in strings when |spell| is enabled.
>
let g:go_highlight_string_spellcheck = 1
<
*'g:go_highlight_format_strings'*
Highlight printf-style formatting verbs inside string literals.
>
let g:go_highlight_format_strings = 1
<
*'g:go_highlight_variable_declarations'*
Highlight variable names in variable declarations (`x` in ` x :=`).
>
let g:go_highlight_variable_declarations = 0
<
*'g:go_highlight_variable_assignments'*
Highlight variable names in variable assignments (`x` in `x =`).
>
let g:go_highlight_variable_assignments = 0
<
==============================================================================
DEVELOPMENT *go-development*
*gohtmltmpl* *ft-gohtmltmpl-syntax*
*gotexttmpl* *ft-gotexttmpl-syntax*
Go template syntax~
vim-go supports test files written in VimL. Please check `autoload` folder for
examples. If you add a new feature be sure you also include the `_test.vim`
file next to the script. Test functions should be starting with `Test_`,
example:
>
function Test_run_fmt()
call assert_equal(expected, actual)
...
endfunction
<
You can locally test it by running:
>
make
<
This will run all tests and print either `PASS` or `FAIL` to indicate the
final status of all tests. Additionally, each new pull request will trigger a
new Travis-ci job.
The `gotexttmpl` 'filetype' provides syntax highlighting and indentation for
Go's `text/template` package.
The `gohtmltmpl` filetype is for use with the `html/template` package and is
identical to `gotexttmpl` except that it will also load the standard `html`
filetype.
The `gohtmltmpl` filetype is automatically set for `*.tmpl` files; the
`gotexttmpl` is never automatically set and needs to be set manually.
==============================================================================
@ -1681,14 +1800,45 @@ After opening vim, run `:echo $PATH`, the output must be your current `$PATH`
plus `$GOPATH/bin` (the location where |:GoInstallBinaries| installed the
binaries).
*go-guru-scope*
What is the guru scope and how do I set it?~
Many vim-go commands use the `guru` commandline tool to get information. Some
`guru` commands require an expensive analysis of the source code. To still get
a reasonable amount of performance `guru` limits this analysis to a selected
list of packages. This is known as the "guru scope".
The default is to use the package the curent buffer belongs to, but this may
not always be correct. For example for the file `guthub.com/user/pkg/a/a.go`
the scope will be set to `github.com/user/pkg/a`, but you probably want
`github.com/user/pkg`
Guessing what package(s) you do want is not easy so you may need to set this
manually, usually from an |autocommand|:
>
autocmd BufRead /home/martin/go/src/github.com/user/pkg/*.go
\ :GoGuruScope github.com/user/pkg
<
If you have a lot of packages with the same prefix (`github.com/user`) you can
use a single autocommand:
>
autocmd BufRead /home/martin/go/src/*.go
\ let s:tmp = matchlist(expand('%:p'),
\ '/home/martin/go/src/\(github.com/user/[^/]\+\)')
\| if len(s:tmp) > 1 | exe 'silent :GoGuruScope ' . s:tmp[1] | endif
\| unlet s:tmp
<
Also see |:GoGuruScope| and |'g:go_guru_scope'|.
Vim becomes slow while editing Go files~
Don't enable these options:
>
let g:go_highlight_types = 0
let g:go_highlight_operators = 0
<
This is usually caused by `g:go_highlight_*` options. Try disabling them if
you've enabled some of them.
Other common culprits are |'g:go_auto_sameids'| and |go#statusline#Show()|.
I get errors when using GoInstallBinaries~
@ -1745,6 +1895,13 @@ not appear. To resolve this:
let g:go_list_type = "quickfix"
<
How do I run focused ginkgo tests?~
You must set this environment variable in your `.vimrc`:
>
let $GINKGO_EDITOR_INTEGRATION = "true"
<
Using with NeoVim~
Note: Neovim currently is not a first class citizen for vim-go. You are free
@ -1764,6 +1921,37 @@ By default new terminals are opened in a vertical split. To change it
let g:go_term_mode = "split"
>
==============================================================================
DEVELOPMENT *go-development*
vim-go supports test files written in VimScript; the way they're run is
roughly similar to Go tests:
- A `*.vim` file has a corresponding `*_test.vim`.
- All functions starting with `Test_` are run as test.
- A test is considered to be "failed" if |v:errors| has any entries. You can
use one of the |test-functions| to set this, or append to it directly.
A simple example:
>
function Test_run_fmt()
call assert_equal(expected, actual)
...
endfunction
<
To run tests vim-go comes with three small helper scripts:
`scripts/install-vim` Install a pristine Vim to `/tmp/vim-go-test/`.
`scripts/run-vim` Run a Vim version from `/tmp/vim-go-test/`.
`scripts/test` Run all tests with a Vim from `/tmp/vim-go-test/`.
All scripts accept a Vim version as the first argument, which can be
`vim-7.4`, `vim-8.0`, or `nvim`. You will need to install a Vim version with
`install-vim` before you can use `run-vim` or `test`.
You can install and test all Vim versions by running `make`.
==============================================================================
DONATION *go-donation*
@ -1773,7 +1961,7 @@ by being a patreon at: https://www.patreon.com/fatih
By being a patron, you are enabling vim-go to grow and mature, helping me to
invest in bug fixes, new documentation, and improving both current and future
features. It's completely optional and is just a direct way to support
Vim-go's ongoing development. Thanks!
vim-go's ongoing development. Thanks!
Check it out: https://www.patreon.com/fatih
@ -1789,4 +1977,4 @@ CREDITS *go-credits*
* vim-go contributors: https://github.com/fatih/vim-go/graphs/contributors.
vim:ft=help:et:ts=2:sw=2:sts=2:norl
vim: ft=help tw=78 et ts=2 sw=2 sts=2 norl

View File

@ -18,14 +18,17 @@ function! s:gofiletype_post()
let &g:fileencodings = s:current_fileencodings
endfunction
au BufNewFile *.go setfiletype go | setlocal fileencoding=utf-8 fileformat=unix
au BufRead *.go call s:gofiletype_pre("go")
au BufReadPost *.go call s:gofiletype_post()
augroup vim-go-filetype
autocmd!
au BufNewFile *.go setfiletype go | setlocal fileencoding=utf-8 fileformat=unix
au BufRead *.go call s:gofiletype_pre("go")
au BufReadPost *.go call s:gofiletype_post()
au BufNewFile *.s setfiletype asm | setlocal fileencoding=utf-8 fileformat=unix
au BufRead *.s call s:gofiletype_pre("asm")
au BufReadPost *.s call s:gofiletype_post()
au BufNewFile *.s setfiletype asm | setlocal fileencoding=utf-8 fileformat=unix
au BufRead *.s call s:gofiletype_pre("asm")
au BufReadPost *.s call s:gofiletype_post()
au BufRead,BufNewFile *.tmpl set filetype=gohtmltmpl
au BufRead,BufNewFile *.tmpl set filetype=gohtmltmpl
augroup end
" vim: sw=2 ts=2 et

View File

@ -1,5 +1,5 @@
" -- gorename
command! -nargs=? GoRename call go#rename#Rename(<bang>0,<f-args>)
command! -nargs=? -complete=customlist,go#rename#Complete GoRename call go#rename#Rename(<bang>0, <f-args>)
" -- guru
command! -nargs=* -complete=customlist,go#package#Complete GoGuruScope call go#guru#Scope(<f-args>)
@ -82,18 +82,9 @@ command! -nargs=* -complete=customlist,go#package#Complete GoErrCheck call go#li
" -- alternate
command! -bang GoAlternate call go#alternate#Switch(<bang>0, '')
" -- ctrlp
if globpath(&rtp, 'plugin/ctrlp.vim') != ""
command! -nargs=? -complete=file GoDecls call ctrlp#init(ctrlp#decls#cmd(0, <q-args>))
command! -nargs=? -complete=dir GoDeclsDir call ctrlp#init(ctrlp#decls#cmd(1, <q-args>))
else
function! s:ctrlp_warning()
call go#util#EchoError("ctrlp.vim plugin is not installed. Please install from: https://github.com/ctrlpvim/ctrlp.vim")
endfunction
command! -nargs=? -complete=file GoDecls call <SID>ctrlp_warning()
command! -nargs=? -complete=file GoDeclsDir call <SID>ctrlp_warning()
endif
" -- decls
command! -nargs=? -complete=file GoDecls call go#decls#Decls(0, <q-args>)
command! -nargs=? -complete=dir GoDeclsDir call go#decls#Decls(1, <q-args>)
" -- impl
command! -nargs=* -buffer -complete=customlist,go#impl#Complete GoImpl call go#impl#Impl(<f-args>)
@ -104,4 +95,7 @@ command! -nargs=0 GoTemplateAutoCreateToggle call go#template#ToggleAutoCreate()
" -- keyify
command! -nargs=0 GoKeyify call go#keyify#Keyify()
" -- fillstruct
command! -nargs=0 GoFillStruct call go#fillstruct#FillStruct()
" vim: sw=2 ts=2 et

View File

@ -1,8 +1,7 @@
if exists("b:did_ftplugin")
finish
endif
let b:did_ftplugin = 1
setlocal commentstring=<!--\ %s\ -->
runtime! ftplugin/html.vim
" vim: sw=2 ts=2 et

View File

@ -110,7 +110,7 @@ snippet gpl
* 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")`
* Copyright (C) ${1:Author}, `!v strftime("%Y")`
*/
${0}
endsnippet

View File

@ -4,36 +4,65 @@ if exists("g:go_loaded_install")
endif
let g:go_loaded_install = 1
" Not using the has('patch-7.4.1689') syntax because that wasn't added until
" 7.4.237, and we want to be sure this works for everyone (this is also why
" we're not using utils#EchoError()).
"
" Version 7.4.1689 was chosen because that's what the most recent Ubuntu LTS
" release (16.04) uses.
if
\ get(g:, 'go_version_warning', 1) != 0 &&
\ (v:version < 704 || (v:version == 704 && !has('patch1689')))
\ && !has('nvim')
echohl Error
echom "vim-go requires Vim 7.4.1689 or Neovim, but you're using an older version."
echom "Please update your Vim for the best vim-go experience."
echom "If you really want to continue you can set this to make the error go away:"
echom " let g:go_version_warning = 0"
echom "Note that some features may error out or behave incorrectly."
echom "Please do not report bugs unless you're using Vim 7.4.1689 or newer."
echohl None
" Make sure people see this.
sleep 2
endif
" these packages are used by vim-go and can be automatically installed if
" needed by the user with GoInstallBinaries
let s:packages = [
\ "github.com/nsf/gocode",
\ "github.com/alecthomas/gometalinter",
\ "golang.org/x/tools/cmd/goimports",
\ "golang.org/x/tools/cmd/guru",
\ "golang.org/x/tools/cmd/gorename",
\ "github.com/golang/lint/golint",
\ "github.com/rogpeppe/godef",
\ "github.com/kisielk/errcheck",
\ "github.com/jstemmer/gotags",
\ "github.com/klauspost/asmfmt/cmd/asmfmt",
\ "github.com/fatih/motion",
\ "github.com/fatih/gomodifytags",
\ "github.com/zmb3/gogetdoc",
\ "github.com/josharian/impl",
\ "github.com/dominikh/go-tools/cmd/keyify",
\ ]
let s:packages = {
\ 'asmfmt': ['github.com/klauspost/asmfmt/cmd/asmfmt'],
\ 'errcheck': ['github.com/kisielk/errcheck'],
\ 'fillstruct': ['github.com/davidrjenni/reftools/cmd/fillstruct'],
\ 'gocode': ['github.com/nsf/gocode', {'windows': '-ldflags -H=windowsgui'}],
\ 'godef': ['github.com/rogpeppe/godef'],
\ 'gogetdoc': ['github.com/zmb3/gogetdoc'],
\ 'goimports': ['golang.org/x/tools/cmd/goimports'],
\ 'golint': ['github.com/golang/lint/golint'],
\ 'gometalinter': ['github.com/alecthomas/gometalinter'],
\ 'gomodifytags': ['github.com/fatih/gomodifytags'],
\ 'gorename': ['golang.org/x/tools/cmd/gorename'],
\ 'gotags': ['github.com/jstemmer/gotags'],
\ 'guru': ['golang.org/x/tools/cmd/guru'],
\ 'impl': ['github.com/josharian/impl'],
\ 'keyify': ['github.com/dominikh/go-tools/cmd/keyify'],
\ 'motion': ['github.com/fatih/motion'],
\ }
" These commands are available on any filetypes
command! GoInstallBinaries call s:GoInstallBinaries(-1)
command! GoUpdateBinaries call s:GoInstallBinaries(1)
command! -nargs=* -complete=customlist,s:complete GoInstallBinaries call s:GoInstallBinaries(-1, <f-args>)
command! -nargs=* -complete=customlist,s:complete GoUpdateBinaries call s:GoInstallBinaries(1, <f-args>)
command! -nargs=? -complete=dir GoPath call go#path#GoPath(<f-args>)
" 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)
fun! s:complete(lead, cmdline, cursor)
return filter(keys(s:packages), 'strpart(v:val, 0, len(a:lead)) == a:lead')
endfun
" GoInstallBinaries downloads and installs binaries defined in s:packages to
" $GOBIN or $GOPATH/bin. GoInstallBinaries will update already installed
" binaries only if updateBinaries = 1. By default, all packages in s:packages
" will be installed, but the set can be limited by passing the desired
" packages in the unnamed arguments.
function! s:GoInstallBinaries(updateBinaries, ...)
let err = s:CheckBinaries()
if err != 0
return
@ -79,26 +108,47 @@ function! s:GoInstallBinaries(updateBinaries)
let cmd .= "-f "
endif
for pkg in s:packages
let basename = fnamemodify(pkg, ":t")
let binname = "go_" . basename . "_bin"
" Filter packages from arguments (if any).
let l:packages = {}
if a:0 > 0
for l:bin in a:000
let l:pkg = get(s:packages, l:bin, [])
if len(l:pkg) == 0
call go#util#EchoError('unknown binary: ' . l:bin)
return
endif
let l:packages[l:bin] = l:pkg
endfor
else
let l:packages = s:packages
endif
let bin = basename
let l:platform = ''
if go#util#IsWin()
let l:platform = 'windows'
endif
for [binary, pkg] in items(l:packages)
let l:importPath = pkg[0]
let l:goGetFlags = len(pkg) > 1 ? get(pkg[1], l:platform, '') : ''
let binname = "go_" . binary . "_bin"
let bin = binary
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
echo "vim-go: Updating " . binary . ". Reinstalling ". importPath . " to folder " . go_bin_path
else
echo "vim-go: ". basename ." not found. Installing ". pkg . " to folder " . go_bin_path
echo "vim-go: ". binary ." not found. Installing ". importPath . " to folder " . go_bin_path
endif
let out = go#util#System(cmd . shellescape(pkg))
let out = go#util#System(cmd . l:goGetFlags . shellescape(importPath))
if go#util#ShellError() != 0
echo "Error installing ". pkg . ": " . out
echom "Error installing " . importPath . ": " . out
endif
endif
endfor

View File

@ -1,81 +1,87 @@
let total_started = reltime()
" Make sure some options are set to sane defaults and output all messages in
" English.
" add vim-go the only plugin inside the runtimepath
let git_root_path = system("git rev-parse --show-toplevel | tr -d '\\n'")
exe 'set rtp=' . git_root_path
" vint: -ProhibitSetNoCompatible
set nocompatible nomore shellslash encoding=utf-8 shortmess+=WIF
lang mess C
" source the passed test file
source %
" cd into the folder of the test file
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
let dir = getcwd()
execute cd . expand('%:p:h')
" initialize variables
let g:testname = expand('%')
" Initialize variables.
let s:total_started = reltime()
let s:fail = 0
let s:done = 0
let s:logs = []
let s:gopath = $GOPATH
" get a list of all Test_ functions for the given file
set nomore
" Source the passed test file.
source %
" cd into the folder of the test file.
let s:cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
let s:testfile = expand('%:t')
execute s:cd . expand('%:p:h')
" Export root path to vim-go dir.
let g:vim_go_root = fnamemodify(getcwd(), ':p')
" Get a list of all Test_ functions for the given file.
redir @q
silent function /^Test_
silent function /^Test_
redir END
let s:tests = split(substitute(@q, 'function \(\k*()\)', '\1', 'g'))
" Iterate over all tests and execute them
" Iterate over all tests and execute them.
for s:test in sort(s:tests)
let started = reltime()
" Since we extract the tests from a regexp the "abort" keyword is also in the
" list, which is not a test name :-)
if s:test == 'abort'
continue
endif
call add(s:logs, printf("=== RUN %s", s:test[:-3]))
let s:started = reltime()
call add(s:logs, printf("=== RUN %s", s:test[:-3]))
exe 'call ' . s:test
let elapsed_time = reltimestr(reltime(started))
let elapsed_time = substitute(elapsed_time, '^\s*\(.\{-}\)\s*$', '\1', '')
" Restore GOPATH after each test.
let $GOPATH = s:gopath
let s:elapsed_time = substitute(reltimestr(reltime(s:started)), '^\s*\(.\{-}\)\s*$', '\1', '')
let s:done += 1
if len(v:errors) > 0
let s:fail += 1
call add(s:logs, printf("--- FAIL: %s (%ss)", s:test[:-3], elapsed_time))
call add(s:logs, printf("--- FAIL %s (%ss)", s:test[:-3], s:elapsed_time))
call extend(s:logs, map(v:errors, '" ". v:val'))
" reset so we can capture failures of next test
" Reset so we can capture failures of the next test.
let v:errors = []
else
call add(s:logs, printf("--- PASS: %s (%ss)", s:test[:-3], elapsed_time))
call add(s:logs, printf("--- PASS %s (%ss)", s:test[:-3], s:elapsed_time))
endif
endfor
" pop out into the scripts folder
execute cd . fnameescape(dir)
" create an empty fail to indicate that the test failed
" Create an empty fail to indicate that at least one test failed.
if s:fail > 0
split FAILED
write
split /tmp/vim-go-test/FAILED
silent write
endif
let total_elapsed_time = reltimestr(reltime(total_started))
let total_elapsed_time = substitute(total_elapsed_time, '^\s*\(.\{-}\)\s*$', '\1', '')
let s:total_elapsed_time = substitute(reltimestr(reltime(s:total_started)), '^\s*\(.\{-}\)\s*$', '\1', '')
let message = 'Executed ' . s:done . (s:done > 1 ? ' tests' : ' test') . '. Total test time: '. total_elapsed_time .'s'
call add(s:logs, "")
call add(s:logs, message)
" store all error messages from within vim into test.log
redir > test.log
silent messages
" Add all messages (usually errors).
redir => s:mess
silent messages
redir END
let s:logs = s:logs + filter(split(s:mess, "\n"), 'v:val !~ "^Messages maintainer"')
" also store all internal messages from s:logs: as well
split test.log
call append(line('$'), '')
call append(line('$'), 'From ' . g:testname . ':')
" Also store all internal messages from s:logs as well.
silent! split /tmp/vim-go-test/test.tmp
call append(line('$'), s:logs)
write
call append(line('$'), printf("%s%s %s / %s tests",
\ (s:fail > 0 ? 'FAIL ' : 'ok '),
\ s:testfile, s:total_elapsed_time, s:done))
silent! write
" bye, bye!
" Our work here is done.
qall!
" vim:ts=2:sts=2:sw=2:et

View File

@ -1,45 +0,0 @@
#!/bin/bash
set -e
cd $(dirname $0)
# install dependencies
go get github.com/fatih/gomodifytags
go get golang.org/x/tools/cmd/goimports
# cleanup test.log
if [ -f "test.log" ]; then
rm test.log
fi
if [ -f "FAILED" ]; then
rm FAILED
fi
for test_file in ../autoload/go/*_test.vim
do
vim -u NONE -S runtest.vim $test_file
done
if [ -f "test.log" ]; then
cat test.log
fi
# if Failed exists, test failed
if [ -f "FAILED" ]; then
echo 2>&1 "FAIL"
exit 1
fi
echo 2>&1 "PASS"
# Run vimhelplint
[ -d vim-vimhelplint ] || git clone https://github.com/machakann/vim-vimhelplint
echo "Running vimhelplint"
lint=$(vim -esN --cmd 'set rtp+=./vim-vimhelplint' -c 'filetype plugin on' \
-c 'e ../doc/vim-go.txt' -c 'verb VimhelpLintEcho' -c q 2>&1)
if [ -n "$lint" ]; then
exit 1
else
exit 0
fi

View File

@ -3,36 +3,13 @@
" 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 off:
"
" - 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.
" - go_highlight_string_spellcheck
" Specifies that strings should be spell checked
" - go_highlight_format_strings
" Highlights printf-style operators inside string literals.
" Quit when a (custom) syntax file was already loaded
if exists("b:current_syntax")
finish
endif
" Set settings to default values.
if !exists("g:go_highlight_array_whitespace_error")
let g:go_highlight_array_whitespace_error = 0
endif
@ -89,10 +66,22 @@ if !exists("g:go_highlight_generate_tags")
let g:go_highlight_generate_tags = 0
endif
if !exists("g:go_highlight_variable_assignments")
let g:go_highlight_variable_assignments = 0
endif
if !exists("g:go_highlight_variable_declarations")
let g:go_highlight_variable_declarations = 0
endif
let s:fold_block = 1
let s:fold_import = 1
let s:fold_varconst = 1
let s:fold_package_comment = 1
let s:fold_comment = 0
if exists("g:go_fold_enable")
" Enabled by default.
if index(g:go_fold_enable, 'block') == -1
let s:fold_block = 0
endif
@ -102,6 +91,14 @@ if exists("g:go_fold_enable")
if index(g:go_fold_enable, 'varconst') == -1
let s:fold_varconst = 0
endif
if index(g:go_fold_enable, 'package_comment') == -1
let s:fold_package_comment = 0
endif
" Disabled by default.
if index(g:go_fold_enable, 'comment') > -1
let s:fold_comment = 1
endif
endif
syn case match
@ -155,8 +152,14 @@ hi def link goPredefinedIdentifiers goBoolean
" 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=goGenerate,@goCommentGroup,@Spell
if s:fold_comment
syn region goComment start="/\*" end="\*/" contains=@goCommentGroup,@Spell fold
syn match goComment "\v(^\s*//.*\n)+" contains=goGenerate,@goCommentGroup,@Spell fold
else
syn region goComment start="/\*" end="\*/" contains=@goCommentGroup,@Spell
endif
hi def link goComment Comment
hi def link goTodo Todo
@ -382,6 +385,18 @@ hi def link goTypeName Type
hi def link goTypeDecl Keyword
hi def link goDeclType Keyword
" Variable Assignments
if g:go_highlight_variable_assignments != 0
syn match goVarAssign /\v[_.[:alnum:]]+(,\s*[_.[:alnum:]]+)*\ze(\s*([-^+|^\/%&]|\*|\<\<|\>\>|\&\^)?\=[^=])/
hi def link goVarAssign Special
endif
" Variable Declarations
if g:go_highlight_variable_declarations != 0
syn match goVarDefs /\v\w+(,\s*\w+)*\ze(\s*:\=)/
hi def link goVarDefs Special
endif
" Build Constraints
if g:go_highlight_build_constraints != 0
syn match goBuildKeyword display contained "+build"
@ -403,15 +418,22 @@ if g:go_highlight_build_constraints != 0
hi def link goBuildCommentStart Comment
hi def link goBuildDirectives Type
hi def link goBuildKeyword PreProc
endif
if g:go_highlight_build_constraints != 0 || s:fold_package_comment
" One or more line comments that are followed immediately by a "package"
" declaration are treated like package documentation, so these must be
" matched as comments to avoid looking like working build constraints.
" The he, me, and re options let the "package" itself be highlighted by
" the usual rules.
syn region goPackageComment start=/\v(\/\/.*\n)+\s*package/
\ end=/\v\n\s*package/he=e-7,me=e-7,re=e-7
\ contains=@goCommentGroup,@Spell
exe 'syn region goPackageComment start=/\v(\/\/.*\n)+\s*package/'
\ . ' end=/\v\n\s*package/he=e-7,me=e-7,re=e-7'
\ . ' contains=@goCommentGroup,@Spell'
\ . (s:fold_package_comment ? ' fold' : '')
exe 'syn region goPackageComment start=/\v\/\*.*\n(.*\n)*\s*\*\/\npackage/'
\ . ' end=/\v\n\s*package/he=e-7,me=e-7,re=e-7'
\ . ' contains=@goCommentGroup,@Spell'
\ . (s:fold_package_comment ? ' fold' : '')
hi def link goPackageComment Comment
endif

View File

@ -2,8 +2,8 @@ if exists("b:current_syntax")
finish
endif
if !exists("main_syntax")
let main_syntax = 'html'
if !exists("g:main_syntax")
let g:main_syntax = 'html'
endif
runtime! syntax/gotexttmpl.vim