1
0
mirror of https://github.com/amix/vimrc synced 2025-06-29 02:55:01 +08:00

Updated plugins

This commit is contained in:
Amir Salihefendic
2019-11-16 16:28:42 +01:00
parent 96e10ed101
commit 72bdaba47e
204 changed files with 5936 additions and 1666 deletions

View File

@ -1,11 +1,10 @@
language: go
go:
- 1.12.1
- 1.13
notifications:
email: false
matrix:
include:
- env: SCRIPT="test -c" VIM_VERSION=vim-7.4
- env: SCRIPT="test -c" VIM_VERSION=vim-8.0
- env: SCRIPT="test -c" VIM_VERSION=nvim
- env: ENV=vimlint SCRIPT=lint VIM_VERSION=vim-8.0
@ -15,9 +14,9 @@ install:
- ./scripts/install-vim $VIM_VERSION
- |
if [ "$ENV" = "vimlint" ]; then
pip install vim-vint covimerage codecov pathlib
pip install vim-vint covimerage==0.1.6 codecov pathlib
else
pip install --user vim-vint covimerage codecov pathlib
pip install --user vim-vint covimerage==0.1.6 codecov pathlib
fi
script:
- ./scripts/$SCRIPT $VIM_VERSION

View File

@ -1,8 +1,91 @@
## unplanned
BACKWARDS INCOMPATABILITIES:
BACKWARDS INCOMPATIBILITIES:
* Drop support for Vim 7.4. The minimum required version of Vim is now 8.0.1453.
[[GH-2495]](https://github.com/fatih/vim-go/pull/2495)
[[GH-2497]](https://github.com/fatih/vim-go/pull/2497)
* Drop support for `gometalinter`
[[GH-2494]](https://github.com/fatih/vim-go/pull/2494)
IMPROVEMENTS:
* Highlight the `go` keyword in go.mod files.
[[GH-2473]](https://github.com/fatih/vim-go/pull/2473)
* Use echo functions consistently.
[[GH-2458]](https://github.com/fatih/vim-go/pull/2458)
* Add support for managing goroutines in debugger.
[[GH-2463]](https://github.com/fatih/vim-go/pull/2463)
[[GH-2527]](https://github.com/fatih/vim-go/pull/2527)
* Document `g:go_doc_popup_window`.
[[GH-2506]](https://github.com/fatih/vim-go/pull/2506)
* Make `g:go_doc_popup_window=1` work for Neovim, too.
[[GH-2451]](https://github.com/fatih/vim-go/pull/2451)
[[GH-2512]](https://github.com/fatih/vim-go/pull/2512)
* Handle errors jumping to a definition in a file open in another Vim process
better.
[[GH-2518]](https://github.com/fatih/vim-go/pull/2518)
* Improve the UX when the gopls binary is missing.
[[GH-2522]](https://github.com/fatih/vim-go/pull/2522)
* Use gopls instead of guru for `:GoSameIds`.
[[GH-2519]](https://github.com/fatih/vim-go/pull/2519)
* Use gopls instead of guru for `:GoReferrers`.
[[GH-2535]](https://github.com/fatih/vim-go/pull/2535)
* Update documentation for `g:go_addtags_transform`.
[[GH-2541]](https://github.com/fatih/vim-go/pull/2541)
* Install most helper tools in module aware mode.
[[GH-2545]](https://github.com/fatih/vim-go/pull/2545)
* Add a new option, `g:go_referrers_mode` to allow the user to choose whether
to use gopls or guru for finding references.
[[GH-2566]](https://github.com/fatih/vim-go/pull/2566)
* Add options to control how gopls responds to completion requests.
[[GH-2567]](https://github.com/fatih/vim-go/pull/2567)
[[GH-2568]](https://github.com/fatih/vim-go/pull/2568)
* Add syntax highlighting for binary literals.
[[GH-2557]](https://github.com/fatih/vim-go/pull/2557)
* Improve highlighting of invalid numeric literals.
[[GH-2571]](https://github.com/fatih/vim-go/pull/2571)
[[GH-2587]](https://github.com/fatih/vim-go/pull/2587)
[[GH-2589]](https://github.com/fatih/vim-go/pull/2589)
* Add highlighting of sections reported by gopls diagnostics' errors
and warnings.
[[GH-2569]](https://github.com/fatih/vim-go/pull/2569)
* Make the highlighting of fzf decls configurable.
[[GH-2572]](https://github.com/fatih/vim-go/pull/2572)
[[GH-2579]](https://github.com/fatih/vim-go/pull/2579)
* Support renaming with gopls.
[[GH-2577]](https://github.com/fatih/vim-go/pull/2577)
BUG FIXES:
* Fix removal of missing directories from gopls workspaces.
[[GH-2507]](https://github.com/fatih/vim-go/pull/2507)
* Change to original window before trying to change directories when term job
ends.
[[GH-2508]](https://github.com/fatih/vim-go/pull/2508)
* Swallow errors when the hover info cannot be determined.
[[GH-2515]](https://github.com/fatih/vim-go/pull/2515)
* Fix errors when trying to debug lsp and hover.
[[GH-2516]](https://github.com/fatih/vim-go/pull/2516)
* Reset environment variables on Vim <= 8.0.1831 .
[[GH-2523]](https://github.com/fatih/vim-go/pull/2523)
* Handle empty results from delve.
[[GH-2526]](https://github.com/fatih/vim-go/pull/2526)
* Do not overwrite `updatetime` when `g:go_auto_sameids` or
`g:go_auto_type_info` is set.
[[GH-2529]](https://github.com/fatih/vim-go/pull/2529)
* Fix example for g:go_debug_log_output in docs.
[[GH-2547]](https://github.com/fatih/vim-go/pull/2547)
* Use FileChangedShellPost instead of FileChangedShell so that reload messages
are not hidden.
[[GH-2549]](https://github.com/fatih/vim-go/pull/2549)
* Restore cwd after `:GoTest` when `g:go_term_enabled` is set.
[[GH-2556]](https://github.com/fatih/vim-go/pull/2556)
* Expand struct variable correctly in the variables debug window.
[[GH-2574]](https://github.com/fatih/vim-go/pull/2574)
## v1.21 - (September 11, 2019)
BACKWARDS INCOMPATIBILITIES:
* `g:go_metalinter_disabled` has been removed.
[[GH-2375]](https://github.com/fatih/vim-go/pull/2117)
[[GH-2375]](https://github.com/fatih/vim-go/pull/2375)
IMPROVEMENTS:
* Add a new option, `g:go_code_completion_enabled`, to control whether omnifunc
@ -59,6 +142,14 @@ IMPROVEMENTS:
[[GH-2453]](https://github.com/fatih/vim-go/pull/2453)
* Reset `'more'` while installing binaries to avoid unnecessary more prompts.
[[GH-2457]](https://github.com/fatih/vim-go/pull/2457)
* Highlight `%w` as a format specifier (for Go 1.13).
[[GH-2433]](https://github.com/fatih/vim-go/pull/2433)
* Handle changes to Go 1.13's go vet output that gometalinter isn't expecting.
[[GH-2475]](https://github.com/fatih/vim-go/pull/2475)
* Make `golangci-lint` the default value for `g:go_metalinter_command`.
[[GH-2478]](https://github.com/fatih/vim-go/pull/2478)
* Parse compiler errors from Go 1.13 `go vet` correctly.
[[GH-2485]](https://github.com/fatih/vim-go/pull/2485)
BUG FIXES:
* display info about function and function types whose parameters are
@ -114,7 +205,14 @@ BUG FIXES:
[[GH-2415]](https://github.com/fatih/vim-go/pull/2401)
* Do not format the file automatically when `g:go_format_autosave` is set and
the file being written is not the current file.
[[GH-2442]](https://github.com/fatih/vim-go/pull/2401)
[[GH-2442]](https://github.com/fatih/vim-go/pull/2442)
* Fix `go-debug-stepout` mapping.
[[GH-2464]](https://github.com/fatih/vim-go/pull/2464)
* Handle paths with spaces correctly when executing jobs.
[[GH-2472]](https://github.com/fatih/vim-go/pull/2472)
* Remove a space in the default value for `g:go_debug_log_output`, so that
Delve will start on Windows.
[[GH-2480]](https://github.com/fatih/vim-go/pull/2480)
## 1.20 - (April 22, 2019)
@ -129,7 +227,7 @@ FEATURES:
* New `:GoDefType` command to jump to a type definition from an instance of the
type.
BACKWARDS INCOMPATABILITIES:
BACKWARDS INCOMPATIBILITIES:
* `g:go_highlight_function_arguments` is renamed to `g:go_highlight_function_parameters`
[[GH-2117]](https://github.com/fatih/vim-go/pull/2117)

View File

@ -1,4 +1,4 @@
FROM golang:1.12.4
FROM golang:1.13
RUN apt-get update -y && \
apt-get install -y build-essential curl git libncurses5-dev python3-pip && \
@ -13,7 +13,6 @@ USER vim-go
COPY . /vim-go/
WORKDIR /vim-go
RUN scripts/install-vim vim-7.4
RUN scripts/install-vim vim-8.0
RUN scripts/install-vim nvim

View File

@ -1,4 +1,4 @@
VIMS ?= vim-7.4 vim-8.0 nvim
VIMS ?= vim-8.0 nvim
all: install lint test

View File

@ -33,7 +33,7 @@ This plugin adds Go language support for Vim, with the following main features:
## Install
vim-go requires at least Vim 7.4.2009 or Neovim 0.3.1.
vim-go requires at least Vim 8.0.1453 or Neovim 0.3.1.
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,
@ -82,3 +82,4 @@ of the information needed when creating a new issue.
## License
The BSD 3-Clause License - see [`LICENSE`](LICENSE) for more details

View File

@ -121,10 +121,10 @@ function! s:source(mode,...) abort
\ decl.col
\)
call add(ret_decls, printf("%s\t%s %s\t%s",
\ s:color(decl.ident . space, "Function"),
\ s:color(decl.keyword, "Keyword"),
\ s:color(pos, "SpecialComment"),
\ s:color(decl.full, "Comment"),
\ s:color(decl.ident . space, "goDeclsFzfFunction"),
\ s:color(decl.keyword, "goDeclsFzfKeyword"),
\ s:color(pos, "goDeclsFzfSpecialComment"),
\ s:color(decl.full, "goDeclsFzfComment"),
\))
endfor

View File

@ -32,22 +32,68 @@ function! go#auto#echo_go_info()
redraws! | echo "vim-go: " | echohl Function | echon item.info | echohl None
endfunction
function! go#auto#auto_type_info()
if !go#config#AutoTypeInfo() || !isdirectory(expand('%:p:h'))
let s:timer_id = 0
" go#auto#update_autocmd() will be called on BufEnter,CursorHold. This
" configures the augroup according to conditions below.
"
" | # | has_timer | should_enable | do |
" |---|-----------|---------------|------------------------------------|
" | 1 | false | false | return early |
" | 2 | true | true | return early |
" | 3 | true | false | clear the group and stop the timer |
" | 4 | false | true | configure the group |
function! go#auto#update_autocmd()
let has_timer = get(b:, 'has_timer')
let should_enable = go#config#AutoTypeInfo() || go#config#AutoSameids()
if (!has_timer && !should_enable) || (has_timer && should_enable)
return
endif
" GoInfo automatic update
call go#tool#Info(0)
if has_timer
augroup vim-go-buffer-auto
autocmd! * <buffer>
augroup END
let b:has_timer = 0
call s:timer_stop()
return
endif
augroup vim-go-buffer-auto
autocmd! * <buffer>
autocmd CursorMoved <buffer> call s:timer_restart()
autocmd BufLeave <buffer> call s:timer_stop()
augroup END
let b:has_timer = 1
call s:timer_start()
endfunction
function! go#auto#auto_sameids()
if !go#config#AutoSameids() || !isdirectory(expand('%:p:h'))
return
function! s:timer_restart()
if isdirectory(expand('%:p:h'))
call s:timer_stop()
call s:timer_start()
endif
endfunction
" GoSameId automatic update
call go#guru#SameIds(0)
function! s:timer_stop()
if s:timer_id
call timer_stop(s:timer_id)
let s:timer_id = 0
endif
endfunction
function! s:timer_start()
let s:timer_id = timer_start(go#config#Updatetime(), function('s:handler'))
endfunction
function! s:handler(timer_id)
if go#config#AutoTypeInfo()
call go#tool#Info(0)
endif
if go#config#AutoSameids()
call go#guru#SameIds(0)
endif
let s:timer_id = 0
endfunction
function! go#auto#fmt_autosave()

View File

@ -32,7 +32,7 @@ function! go#cmd#Build(bang, ...) abort
\ map(copy(a:000), "expand(v:val)") +
\ [".", "errors"]
" Vim and Neovim async.
" Vim and Neovim async
if go#util#has_job()
call s:cmd_job({
\ 'cmd': ['go'] + args,
@ -41,8 +41,15 @@ function! go#cmd#Build(bang, ...) abort
\ 'statustype': 'build'
\})
" Vim 7.4 without async
" Vim without async
else
let l:status = {
\ 'desc': 'current status',
\ 'type': 'build',
\ 'state': "started",
\ }
call go#statusline#Update(expand('%:p:h'), l:status)
let default_makeprg = &makeprg
let &makeprg = "go " . join(go#util#Shelllist(args), ' ')
@ -68,10 +75,16 @@ function! go#cmd#Build(bang, ...) abort
call go#list#Window(l:listtype, len(errors))
if !empty(errors) && !a:bang
call go#list#JumpToFirst(l:listtype)
let l:status.state = 'failed'
else
call go#util#EchoSuccess("[build] SUCCESS")
let l:status.state = 'success'
if go#config#EchoCommandInfo()
call go#util#EchoSuccess("[build] SUCCESS")
endif
endif
call go#statusline#Update(expand('%:p:h'), l:status)
endif
endfunction
@ -134,6 +147,14 @@ function! go#cmd#Run(bang, ...) abort
" anything. Once this is implemented we're going to make :GoRun async
endif
let l:status = {
\ 'desc': 'current status',
\ 'type': 'run',
\ 'state': "started",
\ }
call go#statusline#Update(expand('%:p:h'), l:status)
let cmd = "go run "
let tags = go#config#BuildTags()
if len(tags) > 0
@ -147,12 +168,21 @@ function! go#cmd#Run(bang, ...) abort
exec '!' . cmd . go#util#Shelljoin(map(copy(a:000), "expand(v:val)"), 1)
endif
let l:status.state = 'success'
if v:shell_error
redraws! | echon "vim-go: [run] " | echohl ErrorMsg | echon "FAILED"| echohl None
let l:status.state = 'failed'
if go#config#EchoCommandInfo()
redraws!
call go#util#EchoError('[run] FAILED')
endif
else
redraws! | echon "vim-go: [run] " | echohl Function | echon "SUCCESS"| echohl None
if go#config#EchoCommandInfo()
redraws!
call go#util#EchoSuccess('[run] SUCCESS')
endif
endif
call go#statusline#Update(expand('%:p:h'), l:status)
return
endif
@ -166,8 +196,8 @@ function! go#cmd#Run(bang, ...) abort
let l:listtype = go#list#Type("GoRun")
let l:status.state = 'success'
try
" backup user's errorformat, will be restored once we are finished
let l:old_errorformat = &errorformat
let &errorformat = s:runerrorformat()
@ -185,10 +215,13 @@ function! go#cmd#Run(bang, ...) abort
let l:errors = go#list#Get(l:listtype)
call go#list#Window(l:listtype, len(l:errors))
if !empty(l:errors) && !a:bang
call go#list#JumpToFirst(l:listtype)
if !empty(l:errors)
let l:status.state = 'failed'
if !a:bang
call go#list#JumpToFirst(l:listtype)
endif
endif
call go#statusline#Update(expand('%:p:h'), l:status)
endfunction
" Install installs the package by simple calling 'go install'. If any argument
@ -255,9 +288,18 @@ function! go#cmd#Generate(bang, ...) abort
let &makeprg = "go generate " . goargs . ' ' . gofiles
endif
let l:listtype = go#list#Type("GoGenerate")
let l:status = {
\ 'desc': 'current status',
\ 'type': 'generate',
\ 'state': "started",
\ }
call go#statusline#Update(expand('%:p:h'), l:status)
echon "vim-go: " | echohl Identifier | echon "generating ..."| echohl None
if go#config#EchoCommandInfo()
call go#util#EchoProgress('generating ...')
endif
let l:listtype = go#list#Type("GoGenerate")
try
if l:listtype == "locationlist"
@ -273,13 +315,18 @@ function! go#cmd#Generate(bang, ...) abort
let errors = go#list#Get(l:listtype)
call go#list#Window(l:listtype, len(errors))
if !empty(errors)
let l:status.status = 'failed'
if !a:bang
call go#list#JumpToFirst(l:listtype)
endif
else
redraws! | echon "vim-go: " | echohl Function | echon "[generate] SUCCESS"| echohl None
let l:status.status = 'success'
if go#config#EchoCommandInfo()
redraws!
call go#util#EchoSuccess('[generate] SUCCESS')
endif
endif
call go#statusline#Update(expand(':%:p:h'), l:status)
endfunction
function! s:runerrorformat()

View File

@ -221,7 +221,6 @@ function! s:info_complete(echo, result) abort
endfunction
function! s:trim_bracket(val) abort
echom a:val
let a:val.word = substitute(a:val.word, '[(){}\[\]]\+$', '', '')
return a:val
endfunction
@ -293,11 +292,11 @@ function! go#complete#ToggleAutoTypeInfo() abort
if go#config#AutoTypeInfo()
call go#config#SetAutoTypeInfo(0)
call go#util#EchoProgress("auto type info disabled")
return
end
call go#config#SetAutoTypeInfo(1)
call go#util#EchoProgress("auto type info enabled")
else
call go#config#SetAutoTypeInfo(1)
call go#util#EchoProgress("auto type info enabled")
endif
call go#auto#update_autocmd()
endfunction
" restore Vi compatibility settings

View File

@ -23,12 +23,15 @@ endfunction
func! s:getinfo()
let l:filename = 'complete/complete.go'
let l:tmp = gotest#load_fixture(l:filename)
try
call cursor(8, 3)
call cursor(8, 3)
let expected = 'func Example(s string)'
let actual = go#complete#GetInfo()
call assert_equal(expected, actual)
let expected = 'func Example(s string)'
let actual = go#complete#GetInfo()
call assert_equal(expected, actual)
finally
call delete(l:tmp, 'rf')
endtry
endfunction
" restore Vi compatibility settings

View File

@ -205,9 +205,10 @@ endfunction
function! go#config#DebugWindows() abort
return get(g:, 'go_debug_windows', {
\ 'stack': 'leftabove 20vnew',
\ 'out': 'botright 10new',
\ 'vars': 'leftabove 30vnew',
\ 'stack': 'leftabove 20new',
\ 'goroutines': 'botright 10new',
\ 'out': 'botright 5new',
\ }
\ )
@ -224,7 +225,7 @@ function! go#config#DebugCommands() abort
endfunction
function! go#config#DebugLogOutput() abort
return get(g:, 'go_debug_log_output', 'debugger, rpc')
return get(g:, 'go_debug_log_output', 'debugger,rpc')
endfunction
function! go#config#LspLog() abort
@ -258,7 +259,7 @@ function! go#config#SetTemplateAutocreate(value) abort
endfunction
function! go#config#MetalinterCommand() abort
return get(g:, "go_metalinter_command", "gometalinter")
return get(g:, "go_metalinter_command", "golangci-lint")
endfunction
function! go#config#MetalinterAutosaveEnabled() abort
@ -365,6 +366,11 @@ function! go#config#PlayOpenBrowser() abort
return get(g:, "go_play_open_browser", 1)
endfunction
function! go#config#GorenameCommand() abort
" delegate to go#config#GorenameBin for backwards compatability.
return get(g:, "go_gorename_command", go#config#GorenameBin())
endfunction
function! go#config#GorenameBin() abort
return get(g:, "go_gorename_bin", "gorename")
endfunction
@ -460,6 +466,14 @@ function! go#config#HighlightVariableDeclarations() abort
return get(g:, 'go_highlight_variable_declarations', 0)
endfunction
function! go#config#HighlightDiagnosticErrors() abort
return get(g:, 'go_highlight_diagnostic_errors', 1)
endfunction
function! go#config#HighlightDiagnosticWarnings() abort
return get(g:, 'go_highlight_diagnostic_warnings', 1)
endfunction
function! go#config#HighlightDebug() abort
return get(g:, 'go_highlight_debug', 1)
endfunction
@ -479,6 +493,31 @@ function! go#config#CodeCompletionEnabled() abort
return get(g:, "go_code_completion_enabled", 1)
endfunction
function! go#config#Updatetime() abort
let go_updatetime = get(g:, 'go_updatetime', 800)
return go_updatetime == 0 ? &updatetime : go_updatetime
endfunction
function! go#config#ReferrersMode() abort
return get(g:, 'go_referrers_mode', 'gopls')
endfunction
function! go#config#GoplsCompleteUnimported() abort
return get(g:, 'go_gopls_complete_unimported', 0)
endfunction
function! go#config#GoplsDeepCompletion() abort
return get(g:, 'go_gopls_deep_completion', 1)
endfunction
function! go#config#GoplsFuzzyMatching() abort
return get(g:, 'go_gopls_fuzzy_matching', 1)
endfunction
function! go#config#GoplsUsePlaceholders() abort
return get(g:, 'go_gopls_use_placeholders', 0)
endfunction
" Set the default value. A value of "1" is a shortcut for this, for
" compatibility reasons.
if exists("g:go_gorename_prefill") && g:go_gorename_prefill == 1

View File

@ -0,0 +1,86 @@
" don't spam the user when Vim is started in Vi compatibility mode
let s:cpo_save = &cpo
set cpo&vim
scriptencoding utf-8
func! Test_SetBuildTags() abort
if !go#util#has_job()
return
endif
try
let g:go_def_mode = 'gopls'
let l:dir = 'test-fixtures/config/buildtags'
let l:jumpstart = [0, 4, 2, 0]
execute 'e ' . printf('%s/buildtags.go', l:dir)
let l:jumpstartbuf = bufnr('')
call setpos('.', [l:jumpstartbuf, l:jumpstart[1], l:jumpstart[2], 0])
let l:expectedfilename = printf('%s/foo.go', l:dir)
let l:expected = [0, 5, 1, 0]
call assert_notequal(l:expected, l:jumpstart)
call go#def#Jump('', 0)
let l:start = reltime()
while getpos('.') != l:expected && reltimefloat(reltime(l:start)) < 10
sleep 100m
endwhile
call assert_equal(l:expectedfilename, bufname("%"))
call assert_equal(l:expected, getpos('.'))
execute 'e ' . printf('%s/buildtags.go', l:dir)
" prepare to wait for the workspace/configuration request
let g:go_debug=['lsp']
" set the build constraint
call go#config#SetBuildTags('constrained')
" wait for the workspace/configuration request
let l:lsplog = getbufline('__GOLSP_LOG__', 1, '$')
let l:start = reltime()
while match(l:lsplog, 'workspace/configuration') == -1 && reltimefloat(reltime(l:start)) < 10
sleep 50m
let l:lsplog = getbufline('__GOLSP_LOG__', 1, '$')
endwhile
unlet g:go_debug
" close the __GOLSP_LOG__ window
only
" verify the cursor position within buildtags.go
call setpos('.', [l:jumpstartbuf, l:jumpstart[1], l:jumpstart[2], 0])
call assert_equal(l:jumpstart, getpos('.'))
let l:expectedfilename = printf('%s/constrainedfoo.go', l:dir)
let l:expected = [0, 6, 1, 0]
call assert_notequal(l:expected, l:jumpstart)
call go#def#Jump('', 0)
let l:start = reltime()
while getpos('.') != l:expected && reltimefloat(reltime(l:start)) < 10
sleep 100m
endwhile
call assert_equal(l:expectedfilename, bufname("%"))
call assert_equal(l:expected, getpos('.'))
let l:lsplog = getbufline('__GOLSP_LOG__', 1, '$')
finally
call go#config#SetBuildTags('')
unlet g:go_def_mode
endtry
endfunc
" restore Vi compatibility settings
let &cpo = s:cpo_save
unlet s:cpo_save
" vim: sw=2 ts=2 et

View File

@ -25,10 +25,10 @@ endfunction
" the code. Calling it again reruns the tests and shows the last updated
" coverage.
function! go#coverage#Buffer(bang, ...) abort
" we use matchaddpos() which was introduce with 7.4.330, be sure we have
" it: http://ftp.vim.org/vim/patches/7.4/7.4.330
" check if the version of Vim being tested supports matchaddpos()
if !exists("*matchaddpos")
call go#util#EchoError("GoCoverage is supported with Vim version 7.4-330 or later")
call go#util#EchoError("GoCoverage is not supported by your version of Vim.")
return -1
endif

View File

@ -23,7 +23,7 @@ if !exists('s:start_args')
let s:start_args = []
endif
function! s:groutineID() abort
function! s:goroutineID() abort
return s:state['currentThread'].goroutineID
endfunction
@ -82,7 +82,7 @@ endfunction
function! s:call_jsonrpc(method, ...) abort
if go#util#HasDebug('debugger-commands')
echom 'sending to dlv ' . a:method
call go#util#EchoInfo('sending to dlv ' . a:method)
endif
let l:args = a:000
@ -160,7 +160,7 @@ endfunction
" Populate the stacktrace window.
function! s:show_stacktrace(res) abort
if !has_key(a:res, 'result')
if type(a:res) isnot type({}) || !has_key(a:res, 'result') || empty(a:res.result)
return
endif
@ -279,6 +279,7 @@ function! go#debug#Stop() abort
silent! exe bufwinnr(bufnr('__GODEBUG_STACKTRACE__')) 'wincmd c'
silent! exe bufwinnr(bufnr('__GODEBUG_VARIABLES__')) 'wincmd c'
silent! exe bufwinnr(bufnr('__GODEBUG_OUTPUT__')) 'wincmd c'
silent! exe bufwinnr(bufnr('__GODEBUG_GOROUTINES__')) 'wincmd c'
if has('balloon_eval')
let &ballooneval=s:ballooneval
@ -325,10 +326,10 @@ endfunction
function! s:expand_var() abort
" Get name from struct line.
let name = matchstr(getline('.'), '^[^:]\+\ze: [a-zA-Z0-9\.·]\+{\.\.\.}$')
let name = matchstr(getline('.'), '^[^:]\+\ze: \*\?[a-zA-Z0-9-_/\.]\+\({\.\.\.}\)\?$')
" Anonymous struct
if name == ''
let name = matchstr(getline('.'), '^[^:]\+\ze: struct {.\{-}}$')
let name = matchstr(getline('.'), '^[^:]\+\ze: \*\?struct {.\{-}}$')
endif
if name != ''
@ -418,23 +419,6 @@ function! s:start_cb() abort
endif
let debugwindows = go#config#DebugWindows()
if has_key(debugwindows, "stack") && debugwindows['stack'] != ''
exe 'silent ' . debugwindows['stack']
silent file `='__GODEBUG_STACKTRACE__'`
setlocal buftype=nofile bufhidden=wipe nomodified nobuflisted noswapfile nowrap nonumber nocursorline
setlocal filetype=godebugstacktrace
nmap <buffer> <cr> :<c-u>call <SID>goto_file()<cr>
nmap <buffer> q <Plug>(go-debug-stop)
endif
if has_key(debugwindows, "out") && debugwindows['out'] != ''
exe 'silent ' . debugwindows['out']
silent file `='__GODEBUG_OUTPUT__'`
setlocal buftype=nofile bufhidden=wipe nomodified nobuflisted noswapfile nowrap nonumber nocursorline
setlocal filetype=godebugoutput
nmap <buffer> q <Plug>(go-debug-stop)
endif
if has_key(debugwindows, "vars") && debugwindows['vars'] != ''
exe 'silent ' . debugwindows['vars']
silent file `='__GODEBUG_VARIABLES__'`
@ -445,6 +429,33 @@ function! s:start_cb() abort
nmap <buffer> q <Plug>(go-debug-stop)
endif
if has_key(debugwindows, "stack") && debugwindows['stack'] != ''
exe 'silent ' . debugwindows['stack']
silent file `='__GODEBUG_STACKTRACE__'`
setlocal buftype=nofile bufhidden=wipe nomodified nobuflisted noswapfile nowrap nonumber nocursorline
setlocal filetype=godebugstacktrace
nmap <buffer> <cr> :<c-u>call <SID>goto_file()<cr>
nmap <buffer> q <Plug>(go-debug-stop)
endif
if has_key(debugwindows, "goroutines") && debugwindows['goroutines'] != ''
exe 'silent ' . debugwindows['goroutines']
silent file `='__GODEBUG_GOROUTINES__'`
setlocal buftype=nofile bufhidden=wipe nomodified nobuflisted noswapfile nowrap nonumber nocursorline
setlocal filetype=godebugvariables
call append(0, ["# Goroutines"])
nmap <buffer> <silent> <cr> :<c-u>call go#debug#Goroutine()<cr>
endif
if has_key(debugwindows, "out") && debugwindows['out'] != ''
exe 'silent ' . debugwindows['out']
silent file `='__GODEBUG_OUTPUT__'`
setlocal buftype=nofile bufhidden=wipe nomodified nobuflisted noswapfile nowrap nonumber nocursorline
setlocal filetype=godebugoutput
nmap <buffer> q <Plug>(go-debug-stop)
endif
call win_gotoid(l:winid)
silent! delcommand GoDebugStart
silent! delcommand GoDebugTest
command! -nargs=0 GoDebugContinue call go#debug#Stack('continue')
@ -459,7 +470,7 @@ function! s:start_cb() abort
nnoremap <silent> <Plug>(go-debug-breakpoint) :<C-u>call go#debug#Breakpoint()<CR>
nnoremap <silent> <Plug>(go-debug-next) :<C-u>call go#debug#Stack('next')<CR>
nnoremap <silent> <Plug>(go-debug-step) :<C-u>call go#debug#Stack('step')<CR>
nnoremap <silent> <Plug>(go-debug-stepout) :<C-u>call go#debug#Stack('stepout')<CR>
nnoremap <silent> <Plug>(go-debug-stepout) :<C-u>call go#debug#Stack('stepOut')<CR>
nnoremap <silent> <Plug>(go-debug-continue) :<C-u>call go#debug#Stack('continue')<CR>
nnoremap <silent> <Plug>(go-debug-stop) :<C-u>call go#debug#Stop()<CR>
nnoremap <silent> <Plug>(go-debug-print) :<C-u>call go#debug#Print(expand('<cword>'))<CR>
@ -472,8 +483,6 @@ function! s:start_cb() abort
set ballooneval
endif
call win_gotoid(l:winid)
augroup vim-go-debug
autocmd! * <buffer>
autocmd FileType go nmap <buffer> <F5> <Plug>(go-debug-continue)
@ -487,7 +496,7 @@ endfunction
function! s:err_cb(ch, msg) abort
if get(s:state, 'ready', 0) != 0
call call('s:logger', ['ERR: ', a:ch, a:msg])
call s:logger('ERR: ', a:ch, a:msg)
return
endif
@ -496,7 +505,7 @@ endfunction
function! s:out_cb(ch, msg) abort
if get(s:state, 'ready', 0) != 0
call call('s:logger', ['OUT: ', a:ch, a:msg])
call s:logger('OUT: ', a:ch, a:msg)
return
endif
@ -771,6 +780,92 @@ function! go#debug#Print(arg) abort
endtry
endfunction
function! s:update_goroutines() abort
try
let l:res = s:call_jsonrpc('RPCServer.State')
let l:currentGoroutineID = 0
try
if type(l:res) is type({}) && has_key(l:res, 'result') && !empty(l:res['result'])
let l:currentGoroutineID = l:res["result"]["State"]["currentGoroutine"]["id"]
endif
catch
call go#util#EchoWarning("current goroutine not found...")
endtry
let l:res = s:call_jsonrpc('RPCServer.ListGoroutines')
call s:show_goroutines(l:currentGoroutineID, l:res)
catch
call go#util#EchoError(v:exception)
endtry
endfunction
function! s:show_goroutines(currentGoroutineID, res) abort
let l:goroutines_winid = bufwinid('__GODEBUG_GOROUTINES__')
if l:goroutines_winid == -1
return
endif
let l:winid = win_getid()
call win_gotoid(l:goroutines_winid)
try
setlocal modifiable
silent %delete _
let v = ['# Goroutines']
if type(a:res) isnot type({}) || !has_key(a:res, 'result') || empty(a:res['result'])
call setline(1, v)
return
endif
let l:goroutines = a:res["result"]["Goroutines"]
if len(l:goroutines) == 0
call go#util#EchoWarning("No Goroutines Running Now...")
call setline(1, v)
return
endif
for l:idx in range(len(l:goroutines))
let l:goroutine = l:goroutines[l:idx]
let l:goroutineType = ""
let l:loc = 0
if l:goroutine.startLoc.file != ""
let l:loc = l:goroutine.startLoc
let l:goroutineType = "Start"
endif
if l:goroutine.goStatementLoc.file != ""
let l:loc = l:goroutine.goStatementLoc
let l:goroutineType = "Go"
endif
if l:goroutine.currentLoc.file != ""
let l:loc = l:goroutine.currentLoc
let l:goroutineType = "Runtime"
endif
if l:goroutine.userCurrentLoc.file != ""
let l:loc=l:goroutine.userCurrentLoc
let l:goroutineType = "User"
endif
" The current goroutine can be changed by pressing enter on one of the
" lines listing a non-active goroutine. If the format of either of these
" lines is modified, then make sure that go#debug#Goroutine is also
" changed if needed.
if l:goroutine.id == a:currentGoroutineID
let l:g = printf("* Goroutine %s - %s: %s:%s %s (thread: %s)", l:goroutine.id, l:goroutineType, l:loc.file, l:loc.line, l:loc.function.name, l:goroutine.threadID)
else
let l:g = printf(" Goroutine %s - %s: %s:%s %s (thread: %s)", l:goroutine.id, l:goroutineType, l:loc.file, l:loc.line, l:loc.function.name, l:goroutine.threadID)
endif
let v += [l:g]
endfor
call setline(1, v)
finally
setlocal nomodifiable
call win_gotoid(l:winid)
endtry
endfunction
function! s:update_variables() abort
" FollowPointers requests pointers to be automatically dereferenced.
" MaxVariableRecurse is how far to recurse when evaluating nested types.
@ -778,20 +873,27 @@ function! s:update_variables() abort
" MaxArrayValues is the maximum number of elements read from an array, a slice or a map.
" MaxStructFields is the maximum number of fields read from a struct, -1 will read all fields.
let l:cfg = {
\ 'scope': {'GoroutineID': s:groutineID()},
\ 'scope': {'GoroutineID': s:goroutineID()},
\ 'cfg': {'MaxStringLen': 20, 'MaxArrayValues': 20}
\ }
try
let res = s:call_jsonrpc('RPCServer.ListLocalVars', l:cfg)
let s:state['localVars'] = res.result['Variables']
let s:state['localVars'] = {}
if type(l:res) is type({}) && has_key(l:res, 'result') && !empty(l:res.result)
let s:state['localVars'] = l:res.result['Variables']
endif
catch
call go#util#EchoError(v:exception)
endtry
try
let res = s:call_jsonrpc('RPCServer.ListFunctionArgs', l:cfg)
let s:state['functionArgs'] = res.result['Args']
let s:state['functionArgs'] = {}
if type(l:res) is type({}) && has_key(l:res, 'result') && !empty(l:res.result)
let s:state['functionArgs'] = res.result['Args']
endif
catch
call go#util#EchoError(v:exception)
endtry
@ -816,7 +918,7 @@ endfunction
function! s:update_stacktrace() abort
try
let l:res = s:call_jsonrpc('RPCServer.Stacktrace', {'id': s:groutineID(), 'depth': 5})
let l:res = s:call_jsonrpc('RPCServer.Stacktrace', {'id': s:goroutineID(), 'depth': 5})
call s:show_stacktrace(l:res)
catch
call go#util#EchoError(v:exception)
@ -826,10 +928,12 @@ endfunction
function! s:stack_cb(res) abort
let s:stack_name = ''
if empty(a:res) || !has_key(a:res, 'result')
if type(a:res) isnot type({}) || !has_key(a:res, 'result') || empty(a:res.result)
return
endif
call s:update_breakpoint(a:res)
call s:update_goroutines()
call s:update_stacktrace()
call s:update_variables()
endfunction
@ -861,8 +965,20 @@ function! go#debug#Stack(name) abort
endif
let s:stack_name = l:name
try
let res = s:call_jsonrpc('RPCServer.Command', {'name': l:name})
call s:stack_cb(res)
let l:res = s:call_jsonrpc('RPCServer.Command', {'name': l:name})
if l:name is# 'next'
let l:res2 = l:res
let l:w = 0
while l:w < 1
if l:res2.result.State.NextInProgress == v:true
let l:res2 = s:call_jsonrpc('RPCServer.Command', {'name': 'continue'})
else
break
endif
endwhile
endif
call s:stack_cb(l:res)
catch
call go#util#EchoError(v:exception)
call s:clearState()
@ -899,6 +1015,23 @@ function! s:isActive()
return len(s:state['message']) > 0
endfunction
" Change Goroutine
function! go#debug#Goroutine() abort
let l:goroutineID = substitute(getline('.'), '^ Goroutine \(.\{-1,\}\) - .*', '\1', 'g')
if l:goroutineID <= 0
return
endif
try
let l:res = s:call_jsonrpc('RPCServer.Command', {'Name': 'switchGoroutine', 'GoroutineID': str2nr(l:goroutineID)})
call s:stack_cb(l:res)
call go#util#EchoInfo("Switched goroutine to: " . l:goroutineID)
catch
call go#util#EchoError(v:exception)
endtry
endfunction
" Toggle breakpoint. Returns 0 on success and 1 on failure.
function! go#debug#Breakpoint(...) abort
let l:filename = fnamemodify(expand('%'), ':p:gs!\\!/!')

View File

@ -24,14 +24,15 @@ function! Test_GoDebugStart_Errors() abort
endif
try
let l:tmp = gotest#load_fixture('debug/compilerror/main.go')
let l:expected = [
\ {'lnum': 0, 'bufnr': 0, 'col': 0, 'valid': 0, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': '# debug/compilerror'},
\ {'lnum': 6, 'bufnr': 7, 'col': 22, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': ' syntax error: unexpected newline, expecting comma or )'},
\ {'lnum': 6, 'bufnr': bufnr('%'), 'col': 22, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': ' syntax error: unexpected newline, expecting comma or )'},
\ {'lnum': 0, 'bufnr': 0, 'col': 0, 'valid': 0, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'exit status 2'}
\]
call setqflist([], 'r')
let l:tmp = gotest#load_fixture('debug/compilerror/main.go')
call assert_false(exists(':GoDebugStop'))
let l:cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : 'cd'

View File

@ -162,9 +162,9 @@ function! go#def#jump_to_declaration(out, mode, bin_name) abort
if filename != fnamemodify(expand("%"), ':p:gs?\\?/?')
" jump to existing buffer if, 1. we have enabled it, 2. the buffer is loaded
" and 3. there is buffer window number we switch to
if go#config#DefReuseBuffer() && bufloaded(filename) != 0 && bufwinnr(filename) != -1
" jumpt to existing buffer if it exists
execute bufwinnr(filename) . 'wincmd w'
if go#config#DefReuseBuffer() && bufwinnr(filename) != -1
" jump to existing buffer if it exists
call win_gotoid(bufwinnr(filename))
else
if &modified
let cmd = 'hide edit'
@ -186,7 +186,13 @@ function! go#def#jump_to_declaration(out, mode, bin_name) abort
endif
" open the file and jump to line and column
exec cmd fnameescape(fnamemodify(filename, ':.'))
try
exec cmd fnameescape(fnamemodify(filename, ':.'))
catch
if stridx(v:exception, ':E325:') < 0
call go#util#EchoError(v:exception)
endif
endtry
endif
endif
call cursor(line, col)

View File

@ -77,14 +77,50 @@ endfunction
function! s:GodocView(newposition, position, content) abort
" popup window
if go#config#DocPopupWindow() && exists('*popup_atcursor') && exists('*popup_clear')
call popup_clear()
if go#config#DocPopupWindow()
if exists('*popup_atcursor') && exists('*popup_clear')
call popup_clear()
call popup_atcursor(split(a:content, '\n'), {
\ 'padding': [1, 1, 1, 1],
\ 'borderchars': ['-','|','-','|','+','+','+','+'],
\ "border": [1, 1, 1, 1],
\ })
call popup_atcursor(split(a:content, '\n'), {
\ 'padding': [1, 1, 1, 1],
\ 'borderchars': ['-','|','-','|','+','+','+','+'],
\ "border": [1, 1, 1, 1],
\ })
elseif has('nvim') && exists('*nvim_open_win')
let lines = split(a:content, '\n')
let height = 0
let width = 0
for line in lines
let lw = strdisplaywidth(line)
if lw > width
let width = lw
endif
let height += 1
endfor
let width += 1 " right margin
let max_height = go#config#DocMaxHeight()
if height > max_height
let height = max_height
endif
let buf = nvim_create_buf(v:false, v:true)
call nvim_buf_set_lines(buf, 0, -1, v:true, lines)
let opts = {
\ 'relative': 'cursor',
\ 'row': 1,
\ 'col': 0,
\ 'width': width,
\ 'height': height,
\ 'style': 'minimal',
\ }
call nvim_open_win(buf, v:true, opts)
setlocal nomodified nomodifiable filetype=godoc
" close easily with CR, Esc and q
noremap <buffer> <silent> <CR> :<C-U>close<CR>
noremap <buffer> <silent> <Esc> :<C-U>close<CR>
noremap <buffer> <silent> q :<C-U>close<CR>
endif
return
endif

View File

@ -62,7 +62,7 @@ func! Test_fillstruct_two_line() abort
\ '\tAddress: "",',
\ '}) }'])
finally
"call delete(l:tmp, 'rf')
call delete(l:tmp, 'rf')
endtry
endfunc

View File

@ -120,18 +120,11 @@ function! go#fmt#update_file(source, target)
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')
" 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
" clean up previous list
if l:listtype == "quickfix"
let l:list_title = getqflist({'title': 1})
else
" can't check the title, so assume that the list was for go fmt.
let l:list_title = {'title': 'Format'}
let l:list_title = getloclist(0, {'title': 1})
endif
if has_key(l:list_title, "title") && l:list_title['title'] == "Format"
@ -196,7 +189,6 @@ function! s:show_errors(errors) abort
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
endif
" this closes the window if there are no errors or it opens

View File

@ -232,11 +232,10 @@ function! go#guru#Describe(selected) abort
endfunction
function! go#guru#DescribeInfo(showstatus) abort
" json_encode() and friends are introduced with this patch (7.4.1304)
" vim: https://groups.google.com/d/msg/vim_dev/vLupTNhQhZ8/cDGIk0JEDgAJ
" nvim: https://github.com/neovim/neovim/pull/4131
" check if the version of Vim being tested supports json_decode()
if !exists("*json_decode")
call go#util#EchoError("requires 'json_decode'. Update your Vim/Neovim version.")
call go#util#EchoError("GoDescribeInfo requires 'json_decode'. Update your Vim/Neovim version.")
return
endif
@ -405,44 +404,45 @@ endfunction
" Show all refs to entity denoted by selected identifier
function! go#guru#Referrers(selected) abort
let args = {
\ 'mode': 'referrers',
\ 'format': 'plain',
\ 'selected': a:selected,
\ 'needs_scope': 0,
\ }
let l:mode = go#config#ReferrersMode()
if l:mode == 'guru'
let args = {
\ 'mode': 'referrers',
\ 'format': 'plain',
\ 'selected': a:selected,
\ 'needs_scope': 0,
\ }
call s:run_guru(args)
call s:run_guru(args)
return
elseif l:mode == 'gopls'
let [l:line, l:col] = getpos('.')[1:2]
let [l:line, l:col] = go#lsp#lsp#Position(l:line, l:col)
let l:fname = expand('%:p')
call go#lsp#Referrers(l:fname, l:line, l:col, funcref('s:parse_guru_output'))
return
else
call go#util#EchoWarning('unknown value for g:go_referrers_mode')
endif
endfunction
function! go#guru#SameIds(showstatus) abort
" we use matchaddpos() which was introduce with 7.4.330, be sure we have
" it: http://ftp.vim.org/vim/patches/7.4/7.4.330
" check if the version of Vim being tested supports matchaddpos()
if !exists("*matchaddpos")
call go#util#EchoError("GoSameIds requires 'matchaddpos'. Update your Vim/Neovim version.")
return
endif
" json_encode() and friends are introduced with this patch (7.4.1304)
" vim: https://groups.google.com/d/msg/vim_dev/vLupTNhQhZ8/cDGIk0JEDgAJ
" nvim: https://github.com/neovim/neovim/pull/4131
" check if the version of Vim being tested supports json_decode()
if !exists("*json_decode")
call go#util#EchoError("GoSameIds requires 'json_decode'. Update your Vim/Neovim version.")
return
endif
let args = {
\ 'mode': 'what',
\ 'format': 'json',
\ 'selected': -1,
\ 'needs_scope': 0,
\ 'custom_parse': function('s:same_ids_highlight'),
\ }
if !a:showstatus
let args.disable_progress = 1
endif
call s:run_guru(args)
let [l:line, l:col] = getpos('.')[1:2]
let [l:line, l:col] = go#lsp#lsp#Position(l:line, l:col)
call go#lsp#SameIDs(0, expand('%:p'), l:line, l:col, funcref('s:same_ids_highlight'))
endfunction
function! s:same_ids_highlight(exit_val, output, mode) abort
@ -482,12 +482,16 @@ function! s:same_ids_highlight(exit_val, output, mode) abort
endif
let same_ids = result['sameids']
" highlight the lines
let l:matches = []
for item in same_ids
let pos = split(item, ':')
call matchaddpos('goSameId', [[str2nr(pos[-2]), str2nr(pos[-1]), str2nr(poslen)]])
let l:matches = add(l:matches, [str2nr(pos[-2]), str2nr(pos[-1]), str2nr(poslen)])
endfor
call matchaddpos('goSameId', l:matches)
if go#config#AutoSameids()
" re-apply SameIds at the current cursor position at the time the buffer
" is redisplayed: e.g. :edit, :GoRename, etc.
@ -501,15 +505,7 @@ 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
let l:cleared = go#util#ClearGroupFromMatches('goSameId')
if !l:cleared
return 1
@ -534,11 +530,11 @@ function! go#guru#AutoToggleSameIds() abort
call go#util#EchoProgress("sameids auto highlighting disabled")
call go#guru#ClearSameIds()
call go#config#SetAutoSameids(0)
return
else
call go#util#EchoSuccess("sameids auto highlighting enabled")
call go#config#SetAutoSameids(1)
endif
call go#util#EchoSuccess("sameids auto highlighting enabled")
call go#config#SetAutoSameids(1)
call go#auto#update_autocmd()
endfunction
@ -602,11 +598,9 @@ function! go#guru#DescribeBalloon() abort
return
endif
" json_encode() and friends are introduced with this patch (7.4.1304)
" vim: https://groups.google.com/d/msg/vim_dev/vLupTNhQhZ8/cDGIk0JEDgAJ
" nvim: https://github.com/neovim/neovim/pull/4131
" check if the version of Vim being tested supports json_decode()
if !exists("*json_decode")
call go#util#EchoError("requires 'json_decode'. Update your Vim/Neovim version.")
call go#util#EchoError("GoDescribeBalloon requires 'json_decode'. Update your Vim/Neovim version.")
return
endif

View File

@ -98,6 +98,46 @@ function! Test_gomodVersion_incompatible_highlight() abort
endtry
endfunc
function! Test_numeric_literal_highlight() abort
syntax on
let tests = {
\ 'lone zero': {'group': 'goDecimalInt', 'value': '0'},
\ 'integer': {'group': 'goDecimalInt', 'value': '1234567890'},
\ 'hexadecimal': {'group': 'goHexadecimalInt', 'value': '0x0123456789abdef'},
\ 'hexadecimalErrorLeading': {'group': 'goHexadecimalError', 'value': '0xg0123456789abdef'},
\ 'hexadecimalErrorTrailing': {'group': 'goHexadecimalError', 'value': '0x0123456789abdefg'},
\ 'heXadecimal': {'group': 'goHexadecimalInt', 'value': '0X0123456789abdef'},
\ 'heXadecimalErrorLeading': {'group': 'goHexadecimalError', 'value': '0Xg0123456789abdef'},
\ 'heXadecimalErrorTrailing': {'group': 'goHexadecimalError', 'value': '0X0123456789abdefg'},
\ 'octal': {'group': 'goOctalInt', 'value': '01234567'},
\ 'octalErrorLeading': {'group': 'goOctalError', 'value': '081234567'},
\ 'octalErrorTrailing': {'group': 'goOctalError', 'value': '012345678'},
\ 'binaryInt': {'group': 'goBinaryInt', 'value': '0b0101'},
\ 'binaryErrorLeading': {'group': 'goBinaryError', 'value': '0b20101'},
\ 'binaryErrorTrailing': {'group': 'goBinaryError', 'value': '0b01012'},
\ 'BinaryInt': {'group': 'goBinaryInt', 'value': '0B0101'},
\ 'BinaryErrorLeading': {'group': 'goBinaryError', 'value': '0B20101'},
\ 'BinaryErrorTrailing': {'group': 'goBinaryError', 'value': '0B01012'},
\ }
for kv in items(tests)
let l:dir = gotest#write_file(printf('numeric/%s.go', kv[0]), [
\ 'package numeric',
\ '',
\ printf("var v = %s\x1f", kv[1].value),
\ ])
try
let l:pos = getcurpos()
let l:actual = synIDattr(synID(l:pos[1], l:pos[2], 1), 'name')
call assert_equal(kv[1].group, l:actual, kv[0])
finally
" call delete(l:dir, 'rf')
endtry
endfor
endfunction
" restore Vi compatibility settings
let &cpo = s:cpo_save
unlet s:cpo_save

View File

@ -61,7 +61,7 @@ function! go#job#Options(args)
let state = {
\ 'winid': win_getid(winnr()),
\ 'dir': getcwd(),
\ 'jobdir': fnameescape(expand("%:p:h")),
\ 'jobdir': expand("%:p:h"),
\ 'messages': [],
\ 'bang': 0,
\ 'for': "_job",
@ -72,9 +72,7 @@ function! go#job#Options(args)
\ 'statustype' : ''
\ }
if has("patch-8.0.0902") || has('nvim')
let cbs.cwd = state.jobdir
endif
let cbs.cwd = state.jobdir
if has_key(a:args, 'bang')
let state.bang = a:args.bang
@ -195,7 +193,7 @@ function! go#job#Options(args)
let l:cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : 'cd'
try
" parse the errors relative to self.jobdir
execute l:cd self.jobdir
execute l:cd fnameescape(self.jobdir)
call go#list#ParseFormat(l:listtype, self.errorformat, out, self.for)
let errors = go#list#Get(l:listtype)
finally
@ -295,11 +293,6 @@ function! go#job#Start(cmd, options)
let l:manualcd = 1
let dir = getcwd()
execute l:cd fnameescape(filedir)
elseif !(has("patch-8.0.0902") || has('nvim'))
let l:manualcd = 1
let l:dir = l:options.cwd
execute l:cd fnameescape(l:dir)
call remove(l:options, 'cwd')
endif
if has_key(l:options, '_start')

View File

@ -0,0 +1,53 @@
" don't spam the user when Vim is started in Vi compatibility mode
let s:cpo_save = &cpo
set cpo&vim
func! Test_JobDirWithSpaces()
if !go#util#has_job()
return
endif
try
let l:filename = 'job/dir has spaces/main.go'
let l:tmp = gotest#load_fixture(l:filename)
exe 'cd ' . fnameescape(l:tmp . '/src/job/dir has spaces')
" set the compiler type so that the errorformat option will be set
" correctly.
compiler go
let expected = [{'lnum': 4, 'bufnr': bufnr('%'), 'col': 2, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'undefined: notafunc'}]
" clear the quickfix lists
call setqflist([], 'r')
" go build discards any results when it compiles multiple packages. So we
" pass the `errors` package just as a placeholder with the current folder
" (indicated with '.').
let l:cmd = ['go', 'build', '.', 'errors']
let l:complete = go#promise#New(function('s:complete'), 10000, '')
call go#job#Spawn(l:cmd, {
\ 'for': 'GoBuild',
\ 'complete': l:complete.wrapper,
\ 'statustype': 'build'
\})
let l:out = l:complete.await()
let actual = getqflist()
call gotest#assert_quickfix(actual, l:expected)
finally
call delete(l:tmp, 'rf')
endtry
endfunc
func! s:complete(job, exit_code, messages)
return a:messages
endfunc
" restore Vi compatibility settings
let &cpo = s:cpo_save
unlet s:cpo_save
" vim: sw=2 ts=2 et

View File

@ -11,7 +11,7 @@ function! go#lint#Gometa(bang, autosave, ...) abort
let l:metalinter = go#config#MetalinterCommand()
if l:metalinter == 'gometalinter' || l:metalinter == 'golangci-lint'
if l:metalinter == 'golangci-lint'
let cmd = s:metalintercmd(l:metalinter)
if empty(cmd)
return
@ -32,14 +32,7 @@ function! go#lint#Gometa(bang, autosave, ...) abort
" will be cleared
redraw
if l:metalinter == "gometalinter"
" Include only messages for the active buffer for autosave.
let include = [printf('--include=^%s:.*$', fnamemodify(expand('%:p'), ":."))]
if go#util#has_job()
let include = [printf('--include=^%s:.*$', expand('%:p:t'))]
endif
let cmd += include
elseif l:metalinter == "golangci-lint"
if l:metalinter == "golangci-lint"
let goargs[0] = expand('%:p:h')
endif
endif
@ -52,18 +45,10 @@ function! go#lint#Gometa(bang, autosave, ...) abort
let cmd += goargs
if l:metalinter == "gometalinter"
" Gometalinter can output one of the two, so we look for both:
" <file>:<line>:<column>:<severity>: <message> (<linter>)
" <file>:<line>::<severity>: <message> (<linter>)
" This can be defined by the following errorformat:
let errformat = "%f:%l:%c:%t%*[^:]:\ %m,%f:%l::%t%*[^:]:\ %m"
else
" Golangci-lint can output the following:
" <file>:<line>:<column>: <message> (<linter>)
" This can be defined by the following errorformat:
let errformat = "%f:%l:%c:\ %m"
endif
" Golangci-lint can output the following:
" <file>:<line>:<column>: <message> (<linter>)
" This can be defined by the following errorformat:
let errformat = "%f:%l:%c:\ %m"
if go#util#has_job()
call s:lint_job({'cmd': cmd, 'statustype': l:metalinter, 'errformat': errformat}, a:bang, a:autosave)
@ -80,7 +65,7 @@ function! go#lint#Gometa(bang, autosave, ...) abort
if l:err == 0
call go#list#Clean(l:listtype)
echon "vim-go: " | echohl Function | echon "[metalinter] PASS" | echohl None
call go#util#EchoSuccess('[metalinter] PASS')
else
let l:winid = win_getid(winnr())
" Parse and populate our location list
@ -143,17 +128,17 @@ function! go#lint#Vet(bang, ...) abort
if a:0 == 0
let [l:out, l:err] = go#util#Exec(['go', 'vet', go#package#ImportPath()])
else
let [l:out, l:err] = go#util#ExecInDir(['go', 'tool', 'vet'] + a:000)
let [l:out, l:err] = go#util#Exec(['go', 'vet'] + a:000 + [go#package#ImportPath()])
endif
let l:listtype = go#list#Type("GoVet")
if l:err != 0
let l:winid = win_getid(winnr())
let errorformat = "%-Gexit status %\\d%\\+," . &errorformat
let l:errorformat = "%-Gexit status %\\d%\\+," . &errorformat
call go#list#ParseFormat(l:listtype, l:errorformat, out, "GoVet")
let errors = go#list#Get(l:listtype)
call go#list#Window(l:listtype, len(errors))
if !empty(errors) && !a:bang
let l:errors = go#list#Get(l:listtype)
call go#list#Window(l:listtype, len(l:errors))
if !empty(l:errors) && !a:bang
call go#list#JumpToFirst(l:listtype)
else
call win_gotoid(l:winid)
@ -232,6 +217,7 @@ function! s:lint_job(args, bang, autosave)
if a:autosave
let l:opts.for = "GoMetaLinterAutoSave"
" s:metalinterautosavecomplete is really only needed for golangci-lint
let l:opts.complete = funcref('s:metalinterautosavecomplete', [expand('%:p:t')])
endif
@ -245,9 +231,7 @@ function! s:metalintercmd(metalinter)
let l:cmd = []
let bin_path = go#path#CheckBinPath(a:metalinter)
if !empty(bin_path)
if a:metalinter == "gometalinter"
let l:cmd = s:gometalintercmd(bin_path)
elseif a:metalinter == "golangci-lint"
if a:metalinter == "golangci-lint"
let l:cmd = s:golangcilintcmd(bin_path)
endif
endif
@ -255,19 +239,6 @@ function! s:metalintercmd(metalinter)
return cmd
endfunction
function! s:gometalintercmd(bin_path)
let cmd = [a:bin_path]
let cmd += ["--disable-all"]
" 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"]
return cmd
endfunction
function! s:golangcilintcmd(bin_path)
let cmd = [a:bin_path]
let cmd += ["run"]
@ -287,10 +258,14 @@ function! s:metalinterautosavecomplete(filepath, job, exit_code, messages)
return
endif
let l:file = expand('%:p:t')
let l:idx = len(a:messages) - 1
while l:idx >= 0
if a:messages[l:idx] !~# '^' . a:filepath . ':'
" Go 1.13 changed how go vet output is formatted by prepending a leading
" 'vet :', so account for that, too. This function is really needed for
" gometalinter at all, so the check for Go 1.13's go vet output shouldn't
" be neeeded, but s:lint_job hooks this up even when the
" g:go_metalinter_command is golangci-lint.
if a:messages[l:idx] !~# '^' . a:filepath . ':' && a:messages[l:idx] !~# '^vet: \.[\\/]' . a:filepath . ':'
call remove(a:messages, l:idx)
endif
let l:idx -= 1

View File

@ -2,10 +2,6 @@
let s:cpo_save = &cpo
set cpo&vim
func! Test_Gometa() abort
call s:gometa('gometalinter')
endfunc
func! Test_GometaGolangciLint() abort
call s:gometa('golangci-lint')
endfunc
@ -21,7 +17,7 @@ func! s:gometa(metalinter) abort
\ ]
if a:metalinter == 'golangci-lint'
let expected = [
\ {'lnum': 5, 'bufnr': bufnr('%')+1, 'col': 1, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'exported function `MissingFooDoc` should have comment or be unexported (golint)'}
\ {'lnum': 5, 'bufnr': bufnr('%')+2, 'col': 1, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'exported function `MissingFooDoc` should have comment or be unexported (golint)'}
\ ]
endif
@ -46,10 +42,6 @@ func! s:gometa(metalinter) abort
endtry
endfunc
func! Test_GometaAutoSave() abort
call s:gometaautosave('gometalinter')
endfunc
func! Test_GometaAutoSaveGolangciLint() abort
call s:gometaautosave('golangci-lint')
endfunc
@ -122,6 +114,35 @@ func! Test_Vet() abort
endtry
endfunc
func! Test_Vet_compilererror() abort
let l:tmp = gotest#load_fixture('lint/src/vet/compilererror/compilererror.go')
try
let expected = [
\ {'lnum': 6, 'bufnr': bufnr('%'), 'col': 22, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': "missing ',' before newline in argument list (and 1 more errors)"}
\ ]
let winnr = winnr()
" clear the location lists
call setqflist([], 'r')
call go#lint#Vet(1)
let actual = getqflist()
let start = reltime()
while len(actual) == 0 && reltimefloat(reltime(start)) < 10
sleep 100m
let actual = getqflist()
endwhile
call gotest#assert_quickfix(actual, expected)
finally
call delete(l:tmp, 'rf')
endtry
endfunc
func! Test_Lint_GOPATH() abort
let RestoreGOPATH = go#util#SetEnv('GOPATH', fnameescape(fnamemodify(getcwd(), ':p')) . 'test-fixtures/lint')

View File

@ -49,13 +49,10 @@ endfunction
function! go#list#Populate(listtype, items, title) abort
if a:listtype == "locationlist"
call setloclist(0, a:items, 'r')
" The last argument ({what}) is introduced with 7.4.2200:
" https://github.com/vim/vim/commit/d823fa910cca43fec3c31c030ee908a14c272640
if has("patch-7.4.2200") | call setloclist(0, [], 'a', {'title': a:title}) | endif
call setloclist(0, [], 'a', {'title': a:title})
else
call setqflist(a:items, 'r')
if has("patch-7.4.2200") | call setqflist([], 'a', {'title': a:title}) | endif
call setqflist([], 'a', {'title': a:title})
endif
endfunction
@ -80,10 +77,10 @@ endfunction
function! go#list#Parse(listtype, items, title) abort
if a:listtype == "locationlist"
lgetexpr a:items
if has("patch-7.4.2200") | call setloclist(0, [], 'a', {'title': a:title}) | endif
call setloclist(0, [], 'a', {'title': a:title})
else
cgetexpr a:items
if has("patch-7.4.2200") | call setqflist([], 'a', {'title': a:title}) | endif
call setqflist([], 'a', {'title': a:title})
endif
endfunction

View File

@ -147,7 +147,10 @@ function! s:newlsp() abort
endfunction
function! l:lsp.handleNotification(req) dict abort
" TODO(bc): handle notifications (e.g. window/showMessage).
" TODO(bc): handle more notifications (e.g. window/showMessage).
if a:req.method == 'textDocument/publishDiagnostics'
call s:handleDiagnostics(a:req.params)
endif
endfunction
function! l:lsp.handleResponse(resp) dict abort
@ -296,6 +299,10 @@ function! s:newlsp() abort
endfunction
function! l:lsp.write(msg) dict abort
if empty(get(self, 'job', {}))
return
endif
let l:body = json_encode(a:msg)
let l:data = 'Content-Length: ' . strlen(l:body) . "\r\n\r\n" . l:body
@ -360,7 +367,7 @@ function! s:newlsp() abort
let l:bin_path = go#path#CheckBinPath("gopls")
if empty(l:bin_path)
return
return l:lsp
endif
let l:cmd = [l:bin_path]
@ -601,6 +608,114 @@ function! s:completionErrorHandler(next, error) abort dict
call call(a:next, [-1, []])
endfunction
" go#lsp#SameIDs calls gopls to get the references to the identifier at line
" and col in fname. handler should be a dictionary function that takes a list
" of strings in the form 'file:line:col: message'. handler will be attached to
" a dictionary that manages state (statuslines, sets the winid, etc.). handler
" should take three arguments: an exit_code, a JSON object encoded to a string
" that mimics guru's ouput for `what`, and third mode parameter that only
" exists for compatibility with the guru implementation of SameIDs.
" TODO(bc): refactor to not need the guru adapter.
function! go#lsp#SameIDs(showstatus, fname, line, col, handler) abort
call go#lsp#DidChange(a:fname)
let l:lsp = s:lspfactory.get()
let l:msg = go#lsp#message#References(a:fname, a:line, a:col)
if a:showstatus
let l:state = s:newHandlerState('same ids')
else
let l:state = s:newHandlerState('')
endif
let l:state.handleResult = funcref('s:sameIDsHandler', [function(a:handler, [], l:state)], l:state)
let l:state.error = funcref('s:noop')
return l:lsp.sendMessage(l:msg, l:state)
endfunction
function! s:sameIDsHandler(next, msg) abort dict
let l:furi = go#path#ToURI(expand('%:p'))
let l:result = {
\ 'sameids': [],
\ 'enclosing': [],
\ }
for l:loc in a:msg
if l:loc.uri !=# l:furi
continue
endif
if len(l:result.enclosing) == 0
let l:result.enclosing = [{
\ 'desc': 'identifier',
\ 'start': l:loc.range.start.character+1,
\ 'end': l:loc.range.end.character+1,
\ }]
endif
let l:result.sameids = add(l:result.sameids, printf('%s:%s:%s', go#path#FromURI(l:loc.uri), l:loc.range.start.line+1, l:loc.range.start.character+1))
endfor
call call(a:next, [0, json_encode(l:result), ''])
endfunction
" go#lsp#Referrers calls gopls to get the references to the identifier at line
" and col in fname. handler should be a dictionary function that takes a list
" of strings in the form 'file:line:col: message'. handler will be attached to
" a dictionary that manages state (statuslines, sets the winid, etc.). handler
" should take three arguments: an exit_code, a JSON object encoded to a string
" that mimics guru's ouput for `what`, and third mode parameter that only
" exists for compatibility with the guru implementation of SameIDs.
" TODO(bc): refactor to not need the guru adapter.
function! go#lsp#Referrers(fname, line, col, handler) abort
call go#lsp#DidChange(a:fname)
let l:lsp = s:lspfactory.get()
let l:msg = go#lsp#message#References(a:fname, a:line, a:col)
let l:state = s:newHandlerState('referrers')
let l:state.handleResult = funcref('s:referencesHandler', [function(a:handler, [], l:state)], l:state)
let l:state.error = funcref('s:noop')
return l:lsp.sendMessage(l:msg, l:state)
endfunction
function! s:referencesHandler(next, msg) abort dict
let l:result = []
call sort(a:msg, funcref('s:compareLocations'))
for l:loc in a:msg
let l:fname = go#path#FromURI(l:loc.uri)
let l:line = l:loc.range.start.line+1
let l:bufnr = bufnr(l:fname)
let l:bufinfo = getbufinfo(l:fname)
try
if l:bufnr == -1 || len(l:bufinfo) == 0 || l:bufinfo[0].loaded == 0
let l:filecontents = readfile(l:fname, '', l:line)
else
let l:filecontents = getbufline(l:fname, l:line)
endif
if len(l:filecontents) == 0
continue
endif
let l:content = l:filecontents[-1]
catch
call go#util#EchoError(printf('%s (line %s): %s at %s', l:fname, l:line, v:exception, v:throwpoint))
endtry
let l:item = printf('%s:%s:%s: %s', go#path#FromURI(l:loc.uri), l:line, go#lsp#lsp#PositionOf(l:content, l:loc.range.start.character), l:content)
let l:result = add(l:result, l:item)
endfor
call call(a:next, [0, l:result, ''])
endfunction
function! go#lsp#Hover(fname, line, col, handler) abort
call go#lsp#DidChange(a:fname)
@ -613,15 +728,19 @@ function! go#lsp#Hover(fname, line, col, handler) abort
endfunction
function! s:hoverHandler(next, msg) abort dict
let l:content = split(a:msg.contents.value, '; ')
if len(l:content) > 1
let l:curly = stridx(l:content[0], '{')
let l:content = extend([l:content[0][0:l:curly]], map(extend([l:content[0][l:curly+1:]], l:content[1:]), '"\t" . v:val'))
let l:content[len(l:content)-1] = '}'
endif
try
let l:content = split(a:msg.contents.value, '; ')
if len(l:content) > 1
let l:curly = stridx(l:content[0], '{')
let l:content = extend([l:content[0][0:l:curly]], map(extend([l:content[0][l:curly+1:]], l:content[1:]), '"\t" . v:val'))
let l:content[len(l:content)-1] = '}'
endif
let l:args = [l:content]
call call(a:next, l:args)
let l:args = [l:content]
call call(a:next, l:args)
catch
" TODO(bc): log the message and/or show an error message.
endtry
endfunction
function! go#lsp#Info(showstatus)
@ -746,13 +865,17 @@ function! go#lsp#CleanWorkspaces() abort
let l:missing = []
for l:dir in l:lsp.workspaceDirectories
if !isdirectory(l:dir)
let l:dir = add(l:missing, l:dir)
let l:missing = add(l:missing, l:dir)
call remove(l:lsp.workspaceDirectories, l:i)
continue
endif
let l:i += 1
endfor
if len(l:missing) == 0
return 0
endif
let l:state = s:newHandlerState('')
let l:state.handleResult = funcref('s:noop')
let l:msg = go#lsp#message#ChangeWorkspaceFolders([], l:missing)
@ -789,14 +912,26 @@ function! go#lsp#DebugBrowser() abort
call go#util#OpenBrowser(printf('http://localhost:%d', l:port))
endfunction
function! go#lsp#Exit() abort
call s:exit(0)
endfunction
function! go#lsp#Restart() abort
call s:exit(1)
endfunction
function! s:exit(restart) abort
if !go#util#has_job() || len(s:lspfactory) == 0 || !has_key(s:lspfactory, 'current')
return
endif
let l:lsp = s:lspfactory.get()
let l:lsp.restarting = 1
" reset the factory so that future requests don't use the same instance of
" gopls.
call s:lspfactory.reset()
let l:lsp.restarting = a:restart
let l:state = s:newHandlerState('exit')
@ -810,7 +945,7 @@ function! go#lsp#Restart() abort
return l:retval
endfunction
function! s:debug(event, data) abort
function! s:debugasync(event, data, timer) abort
if !go#util#HasDebug('lsp')
return
endif
@ -842,6 +977,84 @@ function! s:debug(event, data) abort
endtry
endfunction
function! s:debug(event, data, ...) abort
call timer_start(10, function('s:debugasync', [a:event, a:data]))
endfunction
function! s:compareLocations(left, right) abort
if a:left.uri < a:right.uri
return -1
endif
if a:left.uri == a:right.uri && a:left.range.start.line < a:right.range.start.line
return -1
endif
if a:left.uri == a:right.uri && a:left.range.start.line == a:right.range.start.line && a:left.range.start.character < a:right.range.start.character
return -1
endif
if a:left.uri == a:right.uri && a:left.range.start.line == a:right.range.start.line && a:left.range.start.character == a:right.range.start.character
return 0
endif
return 1
endfunction
function! s:handleDiagnostics(data) abort
if !exists("*matchaddpos")
return 0
endif
try
let l:fname = go#path#FromURI(a:data.uri)
if bufnr(l:fname) == bufnr('')
let l:errorMatches = []
let l:warningMatches = []
for l:diag in a:data.diagnostics
if !(l:diag.severity == 1 || l:diag.severity == 2)
continue
endif
let l:range = l:diag.range
if l:range.start.line != l:range.end.line
continue
endif
let l:line = l:range.start.line + 1
let l:col = go#lsp#lsp#PositionOf(getline(l:line), l:range.start.character)
let l:lastcol = go#lsp#lsp#PositionOf(getline(l:line), l:range.end.character)
let l:pos = [l:line, l:col, l:lastcol - l:col + 1]
if l:diag.severity == 1
let l:errorMatches = add(l:errorMatches, l:pos)
elseif l:diag.severity == 2
let l:warningMatches = add(l:warningMatches, l:pos)
endif
endfor
if hlexists('goDiagnosticError')
" clear the old matches just before adding the new ones to keep flicker
" to a minimum.
call go#util#ClearGroupFromMatches('goDiagnosticError')
if go#config#HighlightDiagnosticErrors()
call matchaddpos('goDiagnosticError', l:errorMatches)
endif
endif
if hlexists('goDiagnosticError')
" clear the old matches just before adding the new ones to keep flicker
" to a minimum.
call go#util#ClearGroupFromMatches('goDiagnosticWarning')
if go#config#HighlightDiagnosticWarnings()
call matchaddpos('goDiagnosticWarning', l:warningMatches)
endif
endif
endif
catch
call go#util#EchoError(v:exception)
endtry
endfunction
" restore Vi compatibility settings
let &cpo = s:cpo_save
unlet s:cpo_save

View File

@ -136,6 +136,22 @@ function! go#lsp#message#Completion(file, line, col) abort
\ }
endfunction
function! go#lsp#message#References(file, line, col) abort
return {
\ 'notification': 0,
\ 'method': 'textDocument/references',
\ 'params': {
\ 'textDocument': {
\ 'uri': go#path#ToURI(a:file)
\ },
\ 'position': s:position(a:line, a:col),
\ 'context': {
\ 'includeDeclaration': v:true,
\ },
\ }
\ }
endfunction
function! go#lsp#message#Hover(file, line, col) abort
return {
\ 'notification': 0,
@ -174,6 +190,10 @@ function! go#lsp#message#ConfigurationResult(items) abort
let l:config = {
\ 'buildFlags': [],
\ 'hoverKind': 'NoDocumentation',
\ 'deepCompletion': go#config#GoplsDeepCompletion() ? v:true : v:false,
\ 'fuzzyMatching': go#config#GoplsFuzzyMatching() ? v:true : v:false,
\ 'completeUnimported': go#config#GoplsCompleteUnimported() ? v:true : v:false,
\ 'usePlaceholders': go#config#GoplsUsePlaceholders() ? v:true : v:false,
\ }
let l:buildtags = go#config#BuildTags()
if buildtags isnot ''

View File

@ -37,7 +37,7 @@ function! s:getinfo(str, name)
let l:actual = go#lsp#GetInfo()
call assert_equal(l:expected, l:actual)
finally
"call delete(l:tmp, 'rf')
call delete(l:tmp, 'rf')
unlet g:go_info_mode
endtry
endfunction

View File

@ -83,18 +83,11 @@ function! go#mod#update_file(source, target)
let l:listtype = go#list#Type("GoModFmt")
" the title information was introduced with 7.4-2200
" https://github.com/vim/vim/commit/d823fa910cca43fec3c31c030ee908a14c272640
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
" clean up previous list
if l:listtype == "quickfix"
let l:list_title = getqflist({'title': 1})
else
" can't check the title, so assume that the list was for go fmt.
let l:list_title = {'title': 'Format'}
let l:list_title = getloclist(0, {'title': 1})
endif
if has_key(l:list_title, "title") && l:list_title['title'] == "Format"

View File

@ -39,7 +39,7 @@ function! s:paths() abort
if executable('go')
let s:goroot = go#util#env("goroot")
if go#util#ShellError() != 0
echomsg '''go env GOROOT'' failed'
call go#util#EchoError('`go env GOROOT` failed')
endif
else
let s:goroot = $GOROOT

View File

@ -28,11 +28,11 @@ function! go#path#GoPath(...) abort
let s:initial_go_path = ""
endif
echon "vim-go: " | echohl Function | echon "GOPATH restored to ". $GOPATH | echohl None
call go#util#EchoInfo("GOPATH restored to ". $GOPATH)
return
endif
echon "vim-go: " | echohl Function | echon "GOPATH changed to ". a:1 | echohl None
call go#util#EchoInfo("GOPATH changed to ". a:1)
let s:initial_go_path = $GOPATH
let $GOPATH = a:1
endfunction

View File

@ -4,7 +4,7 @@ set cpo&vim
function! go#play#Share(count, line1, line2) abort
if !executable('curl')
echohl ErrorMsg | echomsg "vim-go: require 'curl' command" | echohl None
call go#util#EchoError('cannot share: curl cannot be found')
return
endif
@ -20,8 +20,7 @@ function! go#play#Share(count, line1, line2) abort
call delete(share_file)
if l:err != 0
echom 'A error has occurred. Run this command to see what the problem is:'
echom go#util#Shelljoin(l:cmd)
call go#util#EchoError(['A error has occurred. Run this command to see what the problem is:', go#util#Shelljoin(l:cmd)])
return
endif
@ -38,7 +37,7 @@ function! go#play#Share(count, line1, line2) abort
call go#util#OpenBrowser(url)
endif
echo "vim-go: snippet uploaded: ".url
call go#util#EchoInfo('snippet uploaded: ' . url)
endfunction

View File

@ -20,8 +20,10 @@ function! go#rename#Rename(bang, ...) abort
let to_identifier = a:1
endif
let l:bin = go#config#GorenameCommand()
" return with a warning if the bin doesn't exist
let bin_path = go#path#CheckBinPath(go#config#GorenameBin())
let bin_path = go#path#CheckBinPath(l:bin)
if empty(bin_path)
return
endif
@ -29,7 +31,18 @@ function! go#rename#Rename(bang, ...) abort
let fname = expand('%:p')
let pos = go#util#OffsetCursor()
let offset = printf('%s:#%d', fname, pos)
let cmd = [bin_path, "-offset", offset, "-to", to_identifier, '-tags', go#config#BuildTags()]
let args = []
if l:bin == 'gorename'
let l:args = extend(l:args, ['-tags', go#config#BuildTags(), '-offset', offset, '-to', to_identifier])
elseif l:bin == 'gopls'
" TODO(bc): use -tags when gopls supports it
let l:args = extend(l:args, ['rename', '-w', l:offset, to_identifier])
else
call go#util#EchoWarning('unexpected rename command')
endif
let l:cmd = extend([l:bin], l:args)
if go#util#has_job()
call s:rename_job({

View File

@ -96,6 +96,9 @@ function! s:on_stdout(job_id, data, event) dict abort
endfunction
function! s:on_exit(job_id, exit_status, event) dict abort
let l:winid = win_getid(winnr())
call win_gotoid(self.winid)
" change to directory where test were run. if we do not do this
" the quickfix items will have the incorrect paths.
" see: https://github.com/fatih/vim-go/issues/2400
@ -103,12 +106,11 @@ function! s:on_exit(job_id, exit_status, event) dict abort
let l:dir = getcwd()
execute l:cd . fnameescape(expand("%:p:h"))
let l:winid = win_getid(winnr())
call win_gotoid(self.winid)
let l:listtype = go#list#Type("_term")
if a:exit_status == 0
call go#list#Clean(l:listtype)
execute l:cd l:dir
call win_gotoid(l:winid)
return
endif
@ -132,6 +134,7 @@ function! s:on_exit(job_id, exit_status, event) dict abort
if empty(l:errors)
call go#util#EchoError( '[' . l:title . '] ' . "FAIL")
execute l:cd l:dir
call win_gotoid(l:winid)
return
endif
@ -143,6 +146,7 @@ function! s:on_exit(job_id, exit_status, event) dict abort
endif
if self.bang
execute l:cd l:dir
call win_gotoid(l:winid)
return
endif

View File

@ -0,0 +1,5 @@
package config
func Example() {
foo()
}

View File

@ -0,0 +1,8 @@
// +build constrained
package config
// foo is constrained and this comment exists to make the line numbers different than foo.go
func foo() {
println("foo")
}

View File

@ -0,0 +1,7 @@
// +build !constrained
package config
func foo() {
println("foo")
}

View File

@ -0,0 +1,3 @@
module config
go 1.13

View File

@ -0,0 +1,6 @@
package main
func main() {
notafunc()
println("vim-go")
}

View File

@ -0,0 +1,7 @@
package main
import "fmt"
func main() {
fmt.Println("vim-go"
}

View File

@ -62,18 +62,7 @@ endfunction
" The (optional) first parameter can be added to indicate the 'cwd' or 'env'
" parameters will be used, which wasn't added until a later version.
function! go#util#has_job(...) abort
if has('nvim')
return 1
endif
" cwd and env parameters to job_start was added in this version.
if a:0 > 0 && a:1 is 1
return has('job') && has("patch-8.0.0902")
endif
" job was introduced in 7.4.xxx however there are multiple bug fixes and one
" of the latest is 8.0.0087 which is required for a stable async API.
return has('job') && has("patch-8.0.0087")
return has('job') || has('nvim')
endfunction
let s:env_cache = {}
@ -556,15 +545,47 @@ function! go#util#SetEnv(name, value) abort
call execute('let $' . a:name . " = '" . a:value . "'")
if l:remove
function! s:remove(name) abort
call execute('unlet $' . a:name)
endfunction
return function('s:remove', [a:name], l:state)
return function('s:unset', [a:name], l:state)
endif
return function('go#util#SetEnv', [a:name, l:oldvalue], l:state)
endfunction
function! go#util#ClearGroupFromMatches(group) abort
if !exists("*matchaddpos")
return 0
endif
let l:cleared = 0
let m = getmatches()
for item in m
if item['group'] == a:group
call matchdelete(item['id'])
let l:cleared = 1
endif
endfor
return l:cleared
endfunction
function! s:unset(name) abort
try
" unlet $VAR was introducted in Vim 8.0.1832, which is newer than the
" minimal version that vim-go supports. Set the environment variable to
" the empty string in that case. It's not perfect, but it will work fine
" for most things, and is really the best alternative that's available.
if !has('patch-8.0.1832')
call go#util#SetEnv(a:name, '')
return
endif
call execute('unlet $' . a:name)
catch
call go#util#EchoError(printf('could not unset $%s: %s', a:name, v:exception))
endtry
endfunction
function! s:noop(...) abort dict
endfunction

View File

@ -31,14 +31,13 @@ endif
" use a different output, for those we define them directly and modify the
" errorformat ourselves. More information at:
" http://vimdoc.sourceforge.net/htmldoc/quickfix.html#errorformat
CompilerSet errorformat =%-G#\ %.%# " Ignore lines beginning with '#' ('# command-line-arguments' line sometimes appears?)
CompilerSet errorformat+=%-G%.%#panic:\ %m " Ignore lines containing 'panic: message'
CompilerSet errorformat+=%Ecan\'t\ load\ package:\ %m " Start of multiline error string is 'can\'t load package'
CompilerSet errorformat+=%A%f:%l:%c:\ %m " Start of multiline unspecified string is 'filename:linenumber:columnnumber:'
CompilerSet errorformat+=%A%f:%l:\ %m " Start of multiline unspecified string is 'filename:linenumber:'
CompilerSet errorformat+=%C%*\\s%m " Continuation of multiline error message is indented
CompilerSet errorformat+=%-G%.%# " All lines not matching any of the above patterns are ignored
CompilerSet errorformat =%-G#\ %.%# " Ignore lines beginning with '#' ('# command-line-arguments' line sometimes appears?)
CompilerSet errorformat+=%-G%.%#panic:\ %m " Ignore lines containing 'panic: message'
CompilerSet errorformat+=%Ecan\'t\ load\ package:\ %m " Start of multiline error string is 'can\'t load package'
CompilerSet errorformat+=%A%\\%%(%[%^:]%\\+:\ %\\)%\\?%f:%l:%c:\ %m " Start of multiline unspecified string is 'filename:linenumber:columnnumber:'
CompilerSet errorformat+=%A%\\%%(%[%^:]%\\+:\ %\\)%\\?%f:%l:\ %m " Start of multiline unspecified string is 'filename:linenumber:'
CompilerSet errorformat+=%C%*\\s%m " Continuation of multiline error message is indented
CompilerSet errorformat+=%-G%.%# " All lines not matching any of the above patterns are ignored
let &cpo = s:save_cpo
unlet s:save_cpo

View File

@ -51,7 +51,7 @@ experience.
* Precise type-safe renaming of identifiers with |:GoRename|.
* 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
* Call `golangci-lint` 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
@ -77,7 +77,7 @@ experience.
==============================================================================
INSTALL *go-install*
vim-go requires at least Vim 7.4.2009 or Neovim 0.3.1. On macOS, if you are
vim-go requires at least Vim 8.0.1453 or Neovim 0.3.2. On macOS, if you are
still using your system version of vim, you can use homebrew to keep your
version of Vim up-to-date with the following terminal command:
>
@ -249,9 +249,7 @@ COMMANDS *go-commands*
not guarantee all reports are genuine problems, but it can find errors not
caught by the compilers.
You may optionally pass any valid go tool vet flags/options. In this case,
`go tool vet` is run in place of `go vet`. For a full list please see
`go tool vet -h`.
You may optionally pass any valid go vet flags/options.
If [!] is not given the first error is jumped to.
@ -622,8 +620,7 @@ CTRL-t
:GoReferrers
The referrers query shows the set of identifiers that refer to the same
object as does the selected identifier, within any package in the analysis
scope.
object as does the selected identifier.
*:GoSameIds*
:GoSameIds
@ -648,13 +645,13 @@ CTRL-t
the cursor. This basically toggles the option |'g:go_auto_sameids'|
on/off.
If enabled it starts highlighting whenever your cursor is staying at the
same position for a configurable period of time (see 'updatetime'). If
disabled it clears and stops automatic highlighting.
same position for a configurable period of time (see |'g:go_updatetime'|).
If disabled it clears and stops automatic highlighting.
*:GoMetaLinter*
:GoMetaLinter! [path]
Calls the underlying `gometalinter` tool and displays all warnings and
Calls the underlying `golangci-lint` tool and displays all warnings and
errors in the |quickfix| window. By default the following linters are
enabled: `vet`, `golint`, and `errcheck`. This can be changed with the
|'g:go_metalinter_enabled'| variable. To override the command completely
@ -668,8 +665,8 @@ CTRL-t
Changes the build tags for various commands. If you have any file that
uses a custom build tag, such as `// +build integration` , this command
can be used to pass it to all tools that accepts tags, such as guru,
gorename, etc.
can be used to pass it to all tools that accepts tags, such as gopls,
guru, gorename, etc.
The build tags is cleared (unset) if `""` is given. If no arguments are
given it prints the current build tags.
@ -835,7 +832,7 @@ CTRL-t
Toggles |'g:go_metalinter_autosave'|.
By default, `gometalinter` messages will be shown in the |location-list|
By default, `golangci-lint` messages will be shown in the |location-list|
window. The list to use can be set using |'g:go_list_type_commands'|.
*:GoTemplateAutoCreateToggle*
@ -1198,13 +1195,12 @@ into the statusline.
*go#complete#Complete()*
Uses `gopls` for autocompletion. By default, it is hooked up to |'omnifunc'|
for Vim8 and Neovim.
Uses `gopls` for autocompletion. By default, it is hooked up to |'omnifunc'|.
*go#complete#GocodeComplete()*
Uses `gocode` for autocompletion. By default, it is hooked up to |'omnifunc'|
for Vim 7.4.
Uses `gocode` for autocompletion.
*go#tool#DescribeBalloon()*
@ -1269,7 +1265,7 @@ with |:GoPlay|. By default it's enabled. >
Use this option to show the type info (|:GoInfo|) for the word under the
cursor automatically. Whenever the cursor changes the type info will be
updated. By default it's disabled. The delay can be configured with the
'g:go_updatetime' setting.
|'g:go_updatetime'| setting.
>
let g:go_auto_type_info = 0
<
@ -1286,15 +1282,16 @@ Valid options are `gocode`, `gopls`, and `guru`.
*'g:go_auto_sameids'*
Use this option to highlight all uses of the identifier under the cursor
(:GoSameIds) automatically. By default it's disabled. The delay can be
configured with the 'g:go_updatetime' setting.
(|:GoSameIds|) automatically. By default it's disabled. The delay can be
configured with the |'g:go_updatetime'| setting.
>
let g:go_auto_sameids = 0
<
*'g:go_updatetime'*
Use this option to configure the a custom 'updatetime' for Go source files. If
set to 0, no custom time will be configured. By default it's set to 800ms.
Use this option to configure the delay until it starts some jobs (see
|'g:go_auto_type_info'|, |'g:go_auto_sameids'|). If set to 0, it uses the
value from 'updatetime'. By default it's set to 800ms.
>
let g:go_updatetime = 800
<
@ -1318,7 +1315,8 @@ Use this option to auto |:GoFmt| on save. By default it's enabled >
*'g:go_fmt_command'*
Use this option to define which tool is used to gofmt. By default `gofmt` is
used >
used.
>
let g:go_fmt_command = "gofmt"
<
@ -1390,6 +1388,14 @@ a private internal service. Default is 'https://godoc.org'.
let g:go_doc_url = 'https://godoc.org'
<
*'g:go_doc_popup_window'*
Use this option to use the popup-window for |K| and |:GoDoc|, rather than the
|preview-window|. Default is disabled.
>
let g:go_doc_popup_window = 0
<
*'g:go_def_mode'*
Use this option to define the command to be used for |:GoDef|. By default
@ -1398,6 +1404,16 @@ accuracy or `godef` for its performance. Valid options are `godef`, `gopls`,
and `guru`.
>
let g:go_def_mode = 'gopls'
<
*'g:go_referrers_mode'*
Use this option to define the command to be used for |:GoReferrers|. By
default `gopls` is used, because it is the fastest and works with Go modules.
One might also use `guru` for its ability to show references from other
packages. This option will be removed after `gopls` can show references from
other packages. Valid options are `gopls` and `guru`.
>
let g:go_referrers_mode = 'gopls'
<
*'g:go_def_mapping_enabled'*
@ -1466,7 +1482,7 @@ pattern. An example input might be:
Also see |go-guru-scope|.
By default it's not set, so the relevant commands defaults are being used.
By default it's not set, so the relevant commands' defaults are being used.
>
let g:go_guru_scope = []
<
@ -1514,7 +1530,7 @@ function when using the `af` text object. By default it's enabled. >
Use this option to auto |:GoMetaLinter| on save. Only linter messages for
the active buffer will be shown.
By default, `gometalinter` messages will be shown in the |location-list|
By default, `golangci-lint` messages will be shown in the |location-list|
window. The list to use can be set using |'g:go_list_type_commands'|.
By default it's disabled >
@ -1543,12 +1559,11 @@ it's empty
<
*'g:go_metalinter_command'*
Overrides the command to be executed when |:GoMetaLinter| is called. By
default it's `gometalinter`. `golangci-lint` is also supported. It can also be
used as an advanced setting for users who want to have more control over
the metalinter.
Overrides the command to be executed when |:GoMetaLinter| is called. By
default it's `golangci-lint`. It can also be used as an advanced setting
for users who want to have more control over the metalinter.
>
let g:go_metalinter_command = "gometalinter"
let g:go_metalinter_command = "golangci-lint"
<
*'g:go_metalinter_deadline'*
@ -1644,7 +1659,7 @@ just like `:GoBuild`. By default it is disabled.
*'g:go_term_close_on_exit'*
This option is Neovim only. If set to 1 it closes the terminal after the
command run in it exits. By default it is enabled.
command run in it exits when the command fails. By default it is enabled.
>
let g:go_term_close_on_exit = 1
<
@ -1654,6 +1669,14 @@ Specifies the command that |:GoAlternate| uses to open the alternate file.
By default it is set to edit.
>
let g:go_alternate_mode = "edit"
<
*'g:go_gorename_command'*
Use this option to define which tool is used to rename. By default `gorename`
is used. Valid options are `gorename` and `gopls`. Warning: as of `gopls`
v0.2.0, it will only rename identifiers in the current package.
>
let g:go_gorename_command = 'gorename'
<
*'g:go_gorename_prefill'*
@ -1697,6 +1720,39 @@ Specifies whether `gocode` should use a different socket type. By default
>
let g:go_gocode_socket_type = 'unix'
<
*'g:go_gopls_complete_unimported'*
Specifies whether `gopls` should include suggestions from unimported packages.
By default it is disabled.
>
let g:go_gopls_complete_unimported = 0
<
*'g:go_gopls_deep_completion'*
Specifies whether `gopls` should use deep completion. By default it is
enabled.
>
let g:go_gopls_deep_completion = 1
<
*'g:go_gopls_fuzzy_matching'*
Specifies whether `gopls` should use fuzzy matching for completions.
By default it is enabled.
>
let g:go_gopls_fuzzy_matching = 1
<
*'g:go_gopls_use_placeholders'*
Specifies whether `gopls` can provide placeholders for function parameters and
struct fields. By default it is disabled.
>
let g:go_gopls_use_placeholders = 0
<
*'g:go_template_autocreate'*
When a new Go file is created, vim-go automatically fills the buffer content
@ -1792,8 +1848,8 @@ default it's 60 seconds. Must be in milliseconds.
Sets the `transform` option for `gomodifytags` when using |:GoAddTags| or if
it's being used for snippet expansion of single fields. Possible options are:
`snakecase`, `camelcase`. For the following case, if `snakecase` is used the
field will be transformed to:
`snakecase`, `camelcase`, `lispcase`, `pascalcase`, `keep`. For the following
case, if `snakecase` is used the field will be transformed to:
>
type T struct {
FooBarQuz string `json:"foo_bar_quz"
@ -1807,7 +1863,7 @@ If "camelcase" is used:
}
<
By default "snakecase" is used. Current values are: ["snakecase",
"camelcase"].
"camelcase", "lispcase", "pascalcase", "keep"].
>
let g:go_addtags_transform = 'snakecase'
<
@ -1968,6 +2024,18 @@ Highlight variable names in variable assignments (`x` in `x =`).
>
let g:go_highlight_variable_assignments = 0
<
*'g:go_highlight_diagnostic_errors'*
Highlight diagnostic errors.
>
let g:go_highlight_diagnostic_errors = 1
<
*'g:go_highlight_diagnostic_warnings'*
Highlight diagnostic warnings.
>
let g:go_highlight_diagnostic_warnings = 1
<
==============================================================================
*gohtmltmpl* *ft-gohtmltmpl-syntax*
@ -2170,17 +2238,20 @@ DEBUGGER SETTINGS~
*'g:go_debug_windows'*
Controls the window layout for debugging mode. This is a |dict| with three
possible keys: "stack", "out", and "vars"; the windows will created in that
order with the commands in the value.
Controls the window layout for debugging mode. This is a |dict| with four
possible keys: "vars", "stack", "goroutines", and "out"; each of the new
windows will be created in that that order with the commands in the value. The
current window is made the only window before creating the debug windows.
A window will not be created if a key is missing or empty.
Defaults:
>
let g:go_debug_windows = {
\ 'stack': 'leftabove 20vnew',
\ 'out': 'botright 10new',
\ 'vars': 'leftabove 30vnew',
\ 'vars': 'leftabove 30vnew',
\ 'stack': 'leftabove 20new',
\ 'goroutines': 'botright 10new',
\ 'out': 'botright 5new',
\ }
<
Show only variables on the right-hand side: >
@ -2199,12 +2270,11 @@ Defaults to `127.0.0.1:8181`:
*'g:go_debug_log_output'*
Specifies log output options for `dlv`. Value should be a single string
of comma-separated options suitable for passing to `dlv`. An empty string
(`''`) will suppress logging entirely.
Default: `'debugger, rpc'`:
Specifies log output options for `dlv`. Value should be a single string of
comma-separated options suitable for passing to `dlv`. An empty string (`''`)
will suppress logging entirely. Default: `'debugger,rpc'`:
>
let g:go_debug_log = 'debugger, rpc'
let g:go_debug_log_output = 'debugger,rpc'
<
*'g:go_highlight_debug'*
@ -2354,9 +2424,9 @@ while saving and opening files. The following fixes this:
let g:syntastic_go_checkers = ['golint', 'govet']
let g:syntastic_mode_map = { 'mode': 'active', 'passive_filetypes': ['go'] }
<
If you want to add errcheck you can use gometalinter as a wrapper
If you want to add errcheck you can use golangci-lint as a wrapper:
>
let g:syntastic_go_checkers = ['golint', 'govet', 'gometalinter']
let g:syntastic_go_checkers = ['golint', 'govet', 'golangci-lint']
let g:syntastic_go_gometalinter_args = ['--disable-all', '--enable=errcheck']
let g:syntastic_mode_map = { 'mode': 'active', 'passive_filetypes': ['go'] }
<
@ -2430,7 +2500,7 @@ To run tests vim-go comes with three small helper scripts:
`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
`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`.

View File

@ -74,10 +74,6 @@ if get(g:, "go_textobj_enabled", 1)
xnoremap <buffer> <silent> [[ :<c-u>call go#textobj#FunctionJump('v', 'prev')<cr>
endif
if go#config#AutoTypeInfo() || go#config#AutoSameids()
let &l:updatetime= get(g:, "go_updatetime", 800)
endif
" Autocommands
" ============================================================================
"
@ -91,12 +87,11 @@ augroup vim-go-buffer
" StdinReadPre, BufWritePost, TextChange, TextChangedI)
if go#util#has_job()
autocmd BufWritePost <buffer> call go#lsp#DidChange(expand('<afile>:p'))
autocmd FileChangedShell <buffer> call go#lsp#DidChange(expand('<afile>:p'))
autocmd FileChangedShellPost <buffer> call go#lsp#DidChange(expand('<afile>:p'))
autocmd BufDelete <buffer> call go#lsp#DidClose(expand('<afile>:p'))
endif
autocmd CursorHold <buffer> call go#auto#auto_type_info()
autocmd CursorHold <buffer> call go#auto#auto_sameids()
autocmd BufEnter,CursorHold <buffer> call go#auto#update_autocmd()
" Echo the identifier information when completion is done. Useful to see
" the signature of a function, etc...

View File

@ -9,30 +9,22 @@ let s:cpo_save = &cpo
set cpo&vim
function! s:checkVersion() abort
" Not using the has('patch-7.4.2009') 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.2009 was chosen because that's greater than what the most recent Ubuntu LTS
" release (16.04) uses and has a couple of features we need (e.g. execute()
" and :message clear).
let l:unsupported = 0
if go#config#VersionWarning() != 0
if has('nvim')
let l:unsupported = !has('nvim-0.3.2')
else
let l:unsupported = (v:version < 704 || (v:version == 704 && !has('patch2009')))
let l:unsupported = !has('patch-8.0.1453')
endif
if l:unsupported == 1
echohl Error
echom "vim-go requires Vim 7.4.2009 or Neovim 0.3.2, but you're using an older version."
echom "vim-go requires at least Vim 8.0.1453 or Neovim 0.3.2, 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.2009 or newer or Neovim 0.3.2."
echom "Please do not report bugs unless you're using at least Vim 8.0.1453 or Neovim 0.3.2."
echohl None
" Make sure people see this.
@ -45,28 +37,30 @@ call s:checkVersion()
" these packages are used by vim-go and can be automatically installed if
" needed by the user with GoInstallBinaries.
" NOTE(bc): varying the binary name and the tail of the import path (e.g.
" gocode-gomod) does not yet work in module aware mode.
let s:packages = {
\ 'asmfmt': ['github.com/klauspost/asmfmt/cmd/asmfmt'],
\ 'dlv': ['github.com/go-delve/delve/cmd/dlv'],
\ 'errcheck': ['github.com/kisielk/errcheck'],
\ 'fillstruct': ['github.com/davidrjenni/reftools/cmd/fillstruct'],
\ 'gocode': ['github.com/mdempsky/gocode', {'windows': ['-ldflags', '-H=windowsgui']}],
\ 'asmfmt': ['github.com/klauspost/asmfmt/cmd/asmfmt@master'],
\ 'dlv': ['github.com/go-delve/delve/cmd/dlv@master'],
\ 'errcheck': ['github.com/kisielk/errcheck@master'],
\ 'fillstruct': ['github.com/davidrjenni/reftools/cmd/fillstruct@master'],
\ 'gocode': ['github.com/mdempsky/gocode@master', {'windows': ['-ldflags', '-H=windowsgui']}],
\ 'gocode-gomod': ['github.com/stamblerre/gocode'],
\ 'godef': ['github.com/rogpeppe/godef'],
\ 'gogetdoc': ['github.com/zmb3/gogetdoc'],
\ 'goimports': ['golang.org/x/tools/cmd/goimports'],
\ 'golint': ['golang.org/x/lint/golint'],
\ 'godef': ['github.com/rogpeppe/godef@master'],
\ 'gogetdoc': ['github.com/zmb3/gogetdoc@master'],
\ 'goimports': ['golang.org/x/tools/cmd/goimports@master'],
\ 'golint': ['golang.org/x/lint/golint@master'],
\ 'gopls': ['golang.org/x/tools/gopls@latest', {}, {'after': function('go#lsp#Restart', [])}],
\ 'gometalinter': ['github.com/alecthomas/gometalinter'],
\ 'golangci-lint': ['github.com/golangci/golangci-lint/cmd/golangci-lint'],
\ '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': ['honnef.co/go/tools/cmd/keyify'],
\ 'motion': ['github.com/fatih/motion'],
\ 'iferr': ['github.com/koron/iferr'],
\ 'golangci-lint': ['github.com/golangci/golangci-lint/cmd/golangci-lint@master'],
\ 'gomodifytags': ['github.com/fatih/gomodifytags@master'],
\ 'gorename': ['golang.org/x/tools/cmd/gorename@master'],
\ 'gotags': ['github.com/jstemmer/gotags@master'],
\ 'guru': ['golang.org/x/tools/cmd/guru@master'],
\ 'impl': ['github.com/josharian/impl@master'],
\ 'keyify': ['honnef.co/go/tools/cmd/keyify@master'],
\ 'motion': ['github.com/fatih/motion@master'],
\ 'iferr': ['github.com/koron/iferr@master'],
\ }
" These commands are available on any filetypes
@ -90,16 +84,14 @@ function! s:GoInstallBinaries(updateBinaries, ...)
endif
if go#path#Default() == ""
echohl Error
echomsg "vim.go: $GOPATH is not set and 'go env GOPATH' returns empty"
echohl None
call go#util#EchoError('$GOPATH is not set and `go env GOPATH` returns empty')
return
endif
let go_bin_path = go#path#BinPath()
" change $GOBIN so go get can automatically install to it
let $GOBIN = go_bin_path
let Restore_gobin = go#util#SetEnv('GOBIN', go_bin_path)
" vim's executable path is looking in PATH so add our go_bin path to it
let Restore_path = go#util#SetEnv('PATH', go_bin_path . go#util#PathListSep() . $PATH)
@ -173,10 +165,17 @@ function! s:GoInstallBinaries(updateBinaries, ...)
execute l:cd . fnameescape(l:tmpdir)
let l:get_cmd = copy(l:get_base_cmd)
" first download the binary
if len(l:pkg) > 1 && get(l:pkg[1], l:platform, []) isnot []
let l:get_cmd += get(l:pkg[1], l:platform, [])
endif
" TODO(bc): how to install the bin to a different name than the
" binary path? go get does not support -o
" let l:get_cmd += ['-o', printf('%s%s%s', go_bin_path, go#util#PathSep(), bin)]
let [l:out, l:err] = go#util#Exec(l:get_cmd + [l:importPath])
if l:err
echom "Error installing " . l:importPath . ": " . l:out
call go#util#EchoError(printf('Error installing %s: %s', l:importPath, l:out))
endif
call call(Restore_modules, [])
@ -191,27 +190,26 @@ function! s:GoInstallBinaries(updateBinaries, ...)
let l:get_cmd += ['-u']
endif
" GO111MODULE must be off to install gometalinter.
let Restore_modules = go#util#SetEnv('GO111MODULE', 'off')
" first download the binary
let [l:out, l:err] = go#util#Exec(l:get_cmd + [l:importPath])
if l:err
echom "Error downloading " . l:importPath . ": " . l:out
call go#util#EchoError(printf('Error downloading %s: %s', l:importPath, l:out))
endif
" and then build and install it
let l:build_cmd = ['go', 'build', '-o', go_bin_path . go#util#PathSep() . bin, l:importPath]
if len(l:pkg) > 1 && get(l:pkg[1], l:platform, '') isnot ''
let l:build_cmd += get(l:pkg[1], l:platform, '')
let l:build_cmd = ['go', 'build']
if len(l:pkg) > 1 && get(l:pkg[1], l:platform, []) isnot []
let l:build_cmd += get(l:pkg[1], l:platform, [])
endif
let l:build_cmd += ['-o', printf('%s%s%s', go_bin_path, go#util#PathSep(), bin), l:importPath]
let [l:out, l:err] = go#util#Exec(l:build_cmd)
if l:err
echom "Error installing " . l:importPath . ": " . l:out
call go#util#EchoError(printf('Error installing %s: %s', l:importPath, l:out))
endif
call call(Restore_modules, [])
endif
@ -223,6 +221,7 @@ function! s:GoInstallBinaries(updateBinaries, ...)
" restore back!
call call(Restore_path, [])
call call(Restore_gobin, [])
if resetshellslash
set shellslash
@ -241,12 +240,12 @@ endfunction
" commands are available.
function! s:CheckBinaries()
if !executable('go')
echohl Error | echomsg "vim-go: go executable not found." | echohl None
call go#util#EchoError('go executable not found.')
return -1
endif
if !executable('git')
echohl Error | echomsg "vim-go: git executable not found." | echohl None
call go#util#EchoError('git executable not found.')
return -1
endif
endfunction

View File

@ -13,7 +13,7 @@ cd "$vimgodir"
if [ -z "${1:-}" ]; then
echo "unknown version: '${1:-}'"
echo "First argument must be 'vim-7.4', 'vim-8.0', or 'nvim'."
echo "First argument must be 'vim-8.0' or 'nvim'."
exit 1
fi

View File

@ -15,16 +15,11 @@ cd "$vimgodir"
vim=${1:-}
case "$vim" in
"vim-7.4")
tag="v7.4.2009"
giturl="https://github.com/vim/vim"
;;
"vim-8.0")
# This follows the version in Arch Linux. Vim's master branch isn't always
# This follows the version in Ubuntu LTS. Vim's master branch isn't always
# stable, and we don't want to have the build fail because Vim introduced a
# bug.
tag="v8.0.1542"
tag="v8.0.1453"
giturl="https://github.com/vim/vim"
;;
@ -36,7 +31,7 @@ case "$vim" in
*)
echo "unknown version: '${1:-}'"
echo "First argument must be 'vim-7.4', 'vim-8.0', or 'nvim'."
echo "First argument must be 'vim-8.0' or 'nvim'."
exit 1
;;
esac

View File

@ -11,7 +11,7 @@ cd "$vimgodir"
#####################################
if [ -z "${1:-}" ]; then
echo "unknown version: '${1:-}'"
echo "First argument must be 'vim-7.4', 'vim-8.0', or 'nvim'."
echo "First argument must be 'vim-8.0' or 'nvim'."
exit 1
fi

View File

@ -17,7 +17,7 @@ shift $((OPTIND - 1))
if [ -z "${1:-}" ]; then
echo "unknown version: '${1:-}'"
echo "First argument must be 'vim-7.4', 'vim-8.0', or 'nvim'."
echo "First argument must be 'vim-8.0' or 'nvim'."
exit 1
fi

View File

@ -74,12 +74,16 @@ for s:test in sort(s:tests)
let v:errors += [v:exception]
endtry
let s:elapsed_time = substitute(reltimestr(reltime(s:started)), '^\s*\(.\{-}\)\s*$', '\1', '')
" Restore GOPATH after each test.
let $GOPATH = s:gopath
" Restore the working directory after each test.
execute s:cd . s:dir
let s:elapsed_time = substitute(reltimestr(reltime(s:started)), '^\s*\(.\{-}\)\s*$', '\1', '')
" exit gopls after each test
call go#lsp#Exit()
let s:done += 1
if len(v:errors) > 0

View File

@ -40,7 +40,7 @@ shift $((OPTIND - 1))
#####################################
if [ -z "${1:-}" ]; then
echo "unknown version: '${1:-}'"
echo "First argument must be 'vim-7.4', 'vim-8.0', or 'nvim'."
echo "First argument must be 'vim-8.0' or 'nvim'."
exit 1
fi

View File

@ -117,7 +117,7 @@ if go#config#HighlightFormatStrings()
\@<=%[-#0 +]*\
\%(\%(\%(\[\d\+\]\)\=\*\)\|\d\+\)\=\
\%(\.\%(\%(\%(\[\d\+\]\)\=\*\)\|\d\+\)\=\)\=\
\%(\[\d\+\]\)\=[vTtbcdoqxXUeEfFgGsp]/ contained containedin=goString,goRawString
\%(\[\d\+\]\)\=[vTtbcdoqxXUeEfFgGspw]/ contained containedin=goString,goRawString
hi def link goFormatSpecifier goSpecialString
endif
@ -162,15 +162,21 @@ endif
syn match goSingleDecl /\%(import\|var\|const\) [^(]\@=/ contains=goImport,goVar,goConst
" Integers
syn match goDecimalInt "\<-\=\d\+\%([Ee][-+]\=\d\+\)\=\>"
syn match goDecimalInt "\<-\=\(0\|[1-9]\d*\)\%([Ee][-+]\=\d\+\)\=\>"
syn match goHexadecimalInt "\<-\=0[xX]\x\+\>"
syn match goHexadecimalError "\<-\=0[xX]\x*[^ \t0-9A-Fa-f]\S*\>"
syn match goOctalInt "\<-\=0\o\+\>"
syn match goOctalError "\<-\=0\o*[89]\d*\>"
syn match goOctalError "\<-\=0[XxBb\]]\@!\o*[^ \t0-7]\S*\>"
syn match goBinaryInt "\<-\=0[bB][01]\+\>"
syn match goBinaryError "\<-\=0[bB][01]*[^ \t01]\S*\>"
hi def link goDecimalInt Integer
hi def link goHexadecimalInt Integer
hi def link goHexadecimalError Error
hi def link goOctalInt Integer
hi def link goOctalError Error
hi def link goBinaryInt Integer
hi def link goBinaryError Error
hi def link Integer Number
" Floating point
@ -382,6 +388,13 @@ hi def link goCoverageNormalText Comment
function! s:hi()
hi def link goSameId Search
hi def link goDiagnosticError SpellBad
hi def link goDiagnosticWarning SpellRare
hi def link goDeclsFzfKeyword Keyword
hi def link goDeclsFzfFunction Function
hi def link goDeclsFzfSpecialComment SpecialComment
hi def link goDeclsFzfComment Comment
" :GoCoverage commands
hi def goCoverageCovered ctermfg=green guifg=#A6E22E

View File

@ -9,17 +9,20 @@ syntax case match
" match keywords
syntax keyword gomodModule module
syntax keyword gomodGo go contained
syntax keyword gomodRequire require
syntax keyword gomodExclude exclude
syntax keyword gomodReplace replace
" require, exclude and replace can be also grouped into block
" require, exclude, replace, and go can be also grouped into block
syntax region gomodRequire start='require (' end=')' transparent contains=gomodRequire,gomodVersion
syntax region gomodExclude start='exclude (' end=')' transparent contains=gomodExclude,gomodVersion
syntax region gomodReplace start='replace (' end=')' transparent contains=gomodReplace,gomodVersion
syntax match gomodGo '^go .*$' transparent contains=gomodGo,gomodGoVersion
" set highlights
highlight default link gomodModule Keyword
highlight default link gomodGo Keyword
highlight default link gomodRequire Keyword
highlight default link gomodExclude Keyword
highlight default link gomodReplace Keyword
@ -36,6 +39,10 @@ highlight default link gomodString String
syntax match gomodReplaceOperator "\v\=\>"
highlight default link gomodReplaceOperator Operator
" match go versions
syntax match gomodGoVersion "1\.\d\+" contained
highlight default link gomodGoVersion Identifier
" highlight versions:
" * vX.Y.Z-pre