Squashed 'vim/bundle/go/' changes from bf390af42..75210b2ba
75210b2ba New release: v1.17 723e92485 Merge pull request #1743 from Carpetsmoker/debug-err 1c308cb7b Show debug errors as errors and not progress 73c88fd53 Fix [[ and ]] jumping 3b5b1480f Add :GoDebugTest (#1728) b4eed1e17 redraw before showing progress message only (#1736) e0ba424d3 Merge pull request #1733 from bhcleek/fix-coverage-prompt b2591c356 redraw before echo baaa1788d Merge pull request #1731 from bhcleek/hide-codecov-comment 50fc7e048 Add codecov.io configuration 37e2587aa update CHANGELOG.md for #1725 bb80ad523 Merge pull request #1725 from bhcleek/fix-term-enabled-behavior bca02bcbd update CHANGELOG.md for #1713 8f72dc96a Merge pull request #1713 from bhcleek/cache-import-path 426621fd5 fix splitright behavior when using a terminal buffer afb8e97d2 remove startinsert and stopinsert pair 702b79560 remove stderr callback f80622f39 Merge pull request #1724 from fatih/list-clear 8d040e197 list: add go#list#Close() 16e932cce list: make Clean() more useful 946330869 Merge pull request #1722 from bhcleek/fix-unlikely-term-race b43a68c88 remove redundant changelog entry 800f2946b close the correct location list 2dcb2d228 update CHANGELOG.md for #1716 and #1721 f16f546cb Merge pull request #1721 from bhcleek/fix-terminal-races fe6008e45 Merge pull request #1716 from bhcleek/fix-go-build-error-parse 45cc21201 Update CHANGELOG.md b58082312 Merge pull request #1701 from fatih/remove-install a26578790 Fix various race conditions when using terminal windows f916e1ee5 parse go build errors correctly in vim8 and neovim dd9b635f7 add test for GoBuild 49f560f71 use go#list#ParseFormat() to parse go vet output 6d68c01b3 add test for GoVet f2b67eaa5 cache import path lookups results d2b0a234f update changelog for #1697 dcbfdf3ab Merge pull request #1697 from bhcleek/async-info 24991559a add comments to explain offset calculations 945b63607 Make sure :GoDebugBreakpoint works after :GoDebugStop (#1706) 1bdc75bfc More reliable way to keep track if the program is running (#1699) 8c6a186da update CHANGELOG.md for #1678 5bc8d9edb Merge pull request #1678 from entombedvirus/rohith/async-guru-neovim 2447029b7 cmd: go 1.10 maintains a build cache now ba2a1e81f neovim: invoke guru functions via async api eaef6f793 Do not steal focus when linting on save in vim8. 1292d1545 Update ChangeLog a9fed3289 add fmt.Errorf() snippet in UltiSnips (#1677) a7dd67d18 Keep current alternate-file name while reading templates (#1675) 01bea987a fix path separator of minisnip_dir (#1698) 8c83eb568 always use gocode's vim format fb2986d8a cancel pending async info job when starting another b237f52ef get type info from gocode asynchronously d9d2d27b2 scope completions variable to autoload/go/complete.vim 2274cb5c5 rename preargs to options 4f9c2e9be Changelog.md: make debugger support more prominent 6cc4fd896 Update ChangeLog 52c6da20e add GoDebug (#1390) 39beabec0 Merge pull request #1685 from fatih/fix-go-build-bang 54de23cc6 job: fix bang variable 6dbac34d3 Merge pull request #1683 from bhcleek/fix-async-job-closure 7ed9a827f avoid race conditions in test async jobs 8f2a66dae avoid race conditions in rename async jobs 83a25f196 avoid race conditions in lint async jobs 73a38ea38 avoid race conditions in async jobs 855c35e2d avoid race conditions in guru async jobs cc0467c3c Ensure that goPackageComment region ends after comment. (#1673) 4e871cbcd update CHANGELOG.md for #1671 6437d161d Merge pull request #1671 from bhcleek/redraw-before-gocode dc3b5011a redraw before calling gocode f72ea5c9e update CHANGELOG.md a037e3608 Merge pull request #1664 from bhcleek/empty-test-message 20d52eb64 match test errors with an empty message 7ec5b4692 Merge branch 'metalinter-autosave-list' 6de9daac4 Merge pull request #1653 from bhcleek/handle-autowriteall 18b989736 Merge pull request #1656 from bhcleek/fix-async-race 5743ce160 update documentation for :GoMetaLinterAutoSave and g:go_metalinter_autosave 5a205d3a5 Update Changelog.md 8d5e37e9d Merge pull request #1654 from bhcleek/fix-lint-press-enter aef5e202b Eliminate race conditions in go test job cc24b5508 Eliminate race conditions in gorename job aa37b4288 Eliminate race conditions in gometalinter job b63ba83b4 Eliminate race conditions in guru job 7c727d9b0 Only return callbacks from go#job#Spawn 8bd171624 fix races in go#job#Spawn callbacks 87878247a document go#job#Spawn 4b146cbdc update Test_GometaAutoSave to use location list f59234991 separate gometalinter error list use cases a3716ce61 do not prompt user to press enter after saving 561365d7f handle autowriteall the same as autowrite ffb2f4369 Merge pull request #1651 from bhcleek/reduce-path-function-scope c7316d5a5 reduce visibility of function 6c5622f44 reduce visibility of function 785f632ae update CHANGELOG.md for #1648 f455b9650 Merge pull request #1648 from bhcleek/metalinter-symmetric-enabled-disabled e3974b603 Fix handling and change name of g:go_metalinter_excludes 30d04ad0e Fix ftdetect (#1645) f12f4c81e Update Changelog.md 19eb0581f Update Changelog.md 8308c8d93 Merge pull request #1557 from Carpetsmoker/highlight_methods bf3160402 Update Changelog.md aa9ee00c8 Merge pull request #1640 from bhcleek/fix-metalinter 7702f5c92 use directory arguments given to :GoMetaLinter 4a0fd5d93 fix relative path regex for gometalinter 7cc58f2f9 add tests to verify metalinter autosave behavior 2ab8f815f Add --include for async runner too 55f1598be Active buffer relative to workdir for gometalint 80730c79c Update Changelog.md 1f675f6eb Merge pull request #1641 from bhcleek/fix-show-test-name-toggle 54c62714a Update Changelog 332965f59 Merge pull request #1639 from hokorobi/improve-snippets-abbr 31e6c2839 respect a changed g:go_test_show_name 1a7150fab snippets: improve abbr descriptions for neosnippet 3ceecc2bf support syntax highlighting for bracketed expression in fmt string (#1634) 204cf8e86 Remove unused screenshot.png (#1635) e88020390 update CHANGELOG.md 8eaa1a4a2 Merge pull request #1633 from bhcleek/test-timeout-errors 816cf4203 fix quickfix list when test duration exceeds timeout 992bed6ae Update changelog.md ab598cc22 doc.vim: small style change and remove unused function b68d13b11 Merge pull request #1629 from stamblerre/master bb9903199 update CHANGELOG.md for #1631 ffdf8001b Merge pull request #1631 from wmatusiak/master bdcfc1064 Fix: GoTestFunc dont respect go_test_timeout 8a45bec4d add additional godoc url configuration 264fe46ef Rename go_highlight_methods to go_highlight_function_calls git-subtree-dir: vim/bundle/go git-subtree-split: 75210b2baccf5dc8d19d60b6d0e3cd171e0b5829main
parent
c7496b2816
commit
2aa6230554
@ -0,0 +1,12 @@
|
||||
---
|
||||
coverage:
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
target: auto
|
||||
threshold: 1
|
||||
base: auto
|
||||
comment: false
|
||||
ignore:
|
||||
- "!autoload/go/*.vim$"
|
||||
- "autoload/go/*_test.vim$"
|
Binary file not shown.
Before Width: | Height: | Size: 747 KiB |
@ -0,0 +1,30 @@
|
||||
func! Test_GoBuildErrors()
|
||||
try
|
||||
let l:filename = 'cmd/bad.go'
|
||||
let l:tmp = gotest#load_fixture(l:filename)
|
||||
exe 'cd ' . l:tmp . '/src/cmd'
|
||||
|
||||
" 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')
|
||||
|
||||
call go#cmd#Build(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, l:expected)
|
||||
finally
|
||||
call delete(l:tmp, 'rf')
|
||||
endtry
|
||||
endfunc
|
||||
|
||||
" vim: sw=2 ts=2 et
|
@ -0,0 +1,904 @@
|
||||
scriptencoding utf-8
|
||||
|
||||
if !exists('g:go_debug_windows')
|
||||
let g:go_debug_windows = {
|
||||
\ 'stack': 'leftabove 20vnew',
|
||||
\ 'out': 'botright 10new',
|
||||
\ 'vars': 'leftabove 30vnew',
|
||||
\ }
|
||||
endif
|
||||
|
||||
if !exists('g:go_debug_address')
|
||||
let g:go_debug_address = '127.0.0.1:8181'
|
||||
endif
|
||||
|
||||
if !exists('s:state')
|
||||
let s:state = {
|
||||
\ 'rpcid': 1,
|
||||
\ 'running': 0,
|
||||
\ 'breakpoint': {},
|
||||
\ 'currentThread': {},
|
||||
\ 'localVars': {},
|
||||
\ 'functionArgs': {},
|
||||
\ 'message': [],
|
||||
\ 'is_test': 0,
|
||||
\}
|
||||
|
||||
if go#util#HasDebug('debugger-state')
|
||||
let g:go_debug_diag = s:state
|
||||
endif
|
||||
endif
|
||||
|
||||
if !exists('s:start_args')
|
||||
let s:start_args = []
|
||||
endif
|
||||
|
||||
function! s:groutineID() abort
|
||||
return s:state['currentThread'].goroutineID
|
||||
endfunction
|
||||
|
||||
function! s:exit(job, status) abort
|
||||
if has_key(s:state, 'job')
|
||||
call remove(s:state, 'job')
|
||||
endif
|
||||
call s:clearState()
|
||||
if a:status > 0
|
||||
call go#util#EchoError(s:state['message'])
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:logger(prefix, ch, msg) abort
|
||||
let l:cur_win = bufwinnr('')
|
||||
let l:log_win = bufwinnr(bufnr('__GODEBUG_OUTPUT__'))
|
||||
if l:log_win == -1
|
||||
return
|
||||
endif
|
||||
exe l:log_win 'wincmd w'
|
||||
|
||||
try
|
||||
setlocal modifiable
|
||||
if getline(1) == ''
|
||||
call setline('$', a:prefix . a:msg)
|
||||
else
|
||||
call append('$', a:prefix . a:msg)
|
||||
endif
|
||||
normal! G
|
||||
setlocal nomodifiable
|
||||
finally
|
||||
exe l:cur_win 'wincmd w'
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! s:call_jsonrpc(method, ...) abort
|
||||
if go#util#HasDebug('debugger-commands')
|
||||
if !exists('g:go_debug_commands')
|
||||
let g:go_debug_commands = []
|
||||
endif
|
||||
echom 'sending to dlv ' . a:method
|
||||
endif
|
||||
|
||||
if len(a:000) > 0 && type(a:000[0]) == v:t_func
|
||||
let Cb = a:000[0]
|
||||
let args = a:000[1:]
|
||||
else
|
||||
let Cb = v:none
|
||||
let args = a:000
|
||||
endif
|
||||
let s:state['rpcid'] += 1
|
||||
let req_json = json_encode({
|
||||
\ 'id': s:state['rpcid'],
|
||||
\ 'method': a:method,
|
||||
\ 'params': args,
|
||||
\})
|
||||
|
||||
try
|
||||
" Use callback
|
||||
if type(Cb) == v:t_func
|
||||
let s:ch = ch_open('127.0.0.1:8181', {'mode': 'nl', 'callback': Cb})
|
||||
call ch_sendraw(s:ch, req_json)
|
||||
|
||||
if go#util#HasDebug('debugger-commands')
|
||||
let g:go_debug_commands = add(g:go_debug_commands, {
|
||||
\ 'request': req_json,
|
||||
\ 'response': Cb,
|
||||
\ })
|
||||
endif
|
||||
return
|
||||
endif
|
||||
|
||||
let ch = ch_open('127.0.0.1:8181', {'mode': 'nl', 'timeout': 20000})
|
||||
call ch_sendraw(ch, req_json)
|
||||
let resp_json = ch_readraw(ch)
|
||||
|
||||
if go#util#HasDebug('debugger-commands')
|
||||
let g:go_debug_commands = add(g:go_debug_commands, {
|
||||
\ 'request': req_json,
|
||||
\ 'response': resp_json,
|
||||
\ })
|
||||
endif
|
||||
|
||||
let obj = json_decode(resp_json)
|
||||
if type(obj) == v:t_dict && has_key(obj, 'error') && !empty(obj.error)
|
||||
throw obj.error
|
||||
endif
|
||||
return obj
|
||||
catch
|
||||
throw substitute(v:exception, '^Vim', '', '')
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
" Update the location of the current breakpoint or line we're halted on based on
|
||||
" response from dlv.
|
||||
function! s:update_breakpoint(res) abort
|
||||
if type(a:res) ==# v:t_none
|
||||
return
|
||||
endif
|
||||
|
||||
let state = a:res.result.State
|
||||
if !has_key(state, 'currentThread')
|
||||
return
|
||||
endif
|
||||
|
||||
let s:state['currentThread'] = state.currentThread
|
||||
let bufs = filter(map(range(1, winnr('$')), '[v:val,bufname(winbufnr(v:val))]'), 'v:val[1]=~"\.go$"')
|
||||
if len(bufs) == 0
|
||||
return
|
||||
endif
|
||||
|
||||
exe bufs[0][0] 'wincmd w'
|
||||
let filename = state.currentThread.file
|
||||
let linenr = state.currentThread.line
|
||||
let oldfile = fnamemodify(expand('%'), ':p:gs!\\!/!')
|
||||
if oldfile != filename
|
||||
silent! exe 'edit' filename
|
||||
endif
|
||||
silent! exe 'norm!' linenr.'G'
|
||||
silent! normal! zvzz
|
||||
silent! sign unplace 9999
|
||||
silent! exe 'sign place 9999 line=' . linenr . ' name=godebugcurline file=' . filename
|
||||
endfunction
|
||||
|
||||
" Populate the stacktrace window.
|
||||
function! s:show_stacktrace(res) abort
|
||||
if !has_key(a:res, 'result')
|
||||
return
|
||||
endif
|
||||
|
||||
let l:stack_win = bufwinnr(bufnr('__GODEBUG_STACKTRACE__'))
|
||||
if l:stack_win == -1
|
||||
return
|
||||
endif
|
||||
|
||||
let l:cur_win = bufwinnr('')
|
||||
exe l:stack_win 'wincmd w'
|
||||
|
||||
try
|
||||
setlocal modifiable
|
||||
silent %delete _
|
||||
for i in range(len(a:res.result.Locations))
|
||||
let loc = a:res.result.Locations[i]
|
||||
call setline(i+1, printf('%s - %s:%d', loc.function.name, fnamemodify(loc.file, ':p'), loc.line))
|
||||
endfor
|
||||
finally
|
||||
setlocal nomodifiable
|
||||
exe l:cur_win 'wincmd w'
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
" Populate the variable window.
|
||||
function! s:show_variables() abort
|
||||
let l:var_win = bufwinnr(bufnr('__GODEBUG_VARIABLES__'))
|
||||
if l:var_win == -1
|
||||
return
|
||||
endif
|
||||
|
||||
let l:cur_win = bufwinnr('')
|
||||
exe l:var_win 'wincmd w'
|
||||
|
||||
try
|
||||
setlocal modifiable
|
||||
silent %delete _
|
||||
|
||||
let v = []
|
||||
let v += ['# Local Variables']
|
||||
if type(get(s:state, 'localVars', [])) is type([])
|
||||
for c in s:state['localVars']
|
||||
let v += split(s:eval_tree(c, 0), "\n")
|
||||
endfor
|
||||
endif
|
||||
|
||||
let v += ['']
|
||||
let v += ['# Function Arguments']
|
||||
if type(get(s:state, 'functionArgs', [])) is type([])
|
||||
for c in s:state['functionArgs']
|
||||
let v += split(s:eval_tree(c, 0), "\n")
|
||||
endfor
|
||||
endif
|
||||
|
||||
call setline(1, v)
|
||||
finally
|
||||
setlocal nomodifiable
|
||||
exe l:cur_win 'wincmd w'
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! s:clearState() abort
|
||||
let s:state['currentThread'] = {}
|
||||
let s:state['localVars'] = {}
|
||||
let s:state['functionArgs'] = {}
|
||||
let s:state['message'] = []
|
||||
silent! sign unplace 9999
|
||||
endfunction
|
||||
|
||||
function! s:stop() abort
|
||||
call s:clearState()
|
||||
if has_key(s:state, 'job')
|
||||
call job_stop(s:state['job'])
|
||||
call remove(s:state, 'job')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! go#debug#Stop() abort
|
||||
" Remove signs.
|
||||
for k in keys(s:state['breakpoint'])
|
||||
let bt = s:state['breakpoint'][k]
|
||||
if bt.id >= 0
|
||||
silent exe 'sign unplace ' . bt.id
|
||||
endif
|
||||
endfor
|
||||
|
||||
" Remove all commands and add back the default commands.
|
||||
for k in map(split(execute('command GoDebug'), "\n")[1:], 'matchstr(v:val, "^\\s*\\zs\\S\\+")')
|
||||
exe 'delcommand' k
|
||||
endfor
|
||||
command! -nargs=* -complete=customlist,go#package#Complete GoDebugStart call go#debug#Start(0, <f-args>)
|
||||
command! -nargs=* -complete=customlist,go#package#Complete GoDebugTest call go#debug#Start(1, <f-args>)
|
||||
command! -nargs=? GoDebugBreakpoint call go#debug#Breakpoint(<f-args>)
|
||||
|
||||
" Remove all mappings.
|
||||
for k in map(split(execute('map <Plug>(go-debug-'), "\n")[1:], 'matchstr(v:val, "^n\\s\\+\\zs\\S\\+")')
|
||||
exe 'unmap' k
|
||||
endfor
|
||||
|
||||
call s:stop()
|
||||
|
||||
let bufs = filter(map(range(1, winnr('$')), '[v:val,bufname(winbufnr(v:val))]'), 'v:val[1]=~"\.go$"')
|
||||
if len(bufs) > 0
|
||||
exe bufs[0][0] 'wincmd w'
|
||||
else
|
||||
wincmd p
|
||||
endif
|
||||
silent! exe bufwinnr(bufnr('__GODEBUG_STACKTRACE__')) 'wincmd c'
|
||||
silent! exe bufwinnr(bufnr('__GODEBUG_VARIABLES__')) 'wincmd c'
|
||||
silent! exe bufwinnr(bufnr('__GODEBUG_OUTPUT__')) 'wincmd c'
|
||||
|
||||
set noballooneval
|
||||
set balloonexpr=
|
||||
endfunction
|
||||
|
||||
function! s:goto_file() abort
|
||||
let m = matchlist(getline('.'), ' - \(.*\):\([0-9]\+\)$')
|
||||
if m[1] == ''
|
||||
return
|
||||
endif
|
||||
let bufs = filter(map(range(1, winnr('$')), '[v:val,bufname(winbufnr(v:val))]'), 'v:val[1]=~"\.go$"')
|
||||
if len(bufs) == 0
|
||||
return
|
||||
endif
|
||||
exe bufs[0][0] 'wincmd w'
|
||||
let filename = m[1]
|
||||
let linenr = m[2]
|
||||
let oldfile = fnamemodify(expand('%'), ':p:gs!\\!/!')
|
||||
if oldfile != filename
|
||||
silent! exe 'edit' filename
|
||||
endif
|
||||
silent! exe 'norm!' linenr.'G'
|
||||
silent! normal! zvzz
|
||||
endfunction
|
||||
|
||||
function! s:delete_expands()
|
||||
let nr = line('.')
|
||||
while 1
|
||||
let l = getline(nr+1)
|
||||
if empty(l) || l =~ '^\S'
|
||||
return
|
||||
endif
|
||||
silent! exe (nr+1) . 'd _'
|
||||
endwhile
|
||||
silent! exe 'norm!' nr.'G'
|
||||
endfunction
|
||||
|
||||
function! s:expand_var() abort
|
||||
" Get name from struct line.
|
||||
let name = matchstr(getline('.'), '^[^:]\+\ze: [a-zA-Z0-9\.·]\+{\.\.\.}$')
|
||||
" Anonymous struct
|
||||
if name == ''
|
||||
let name = matchstr(getline('.'), '^[^:]\+\ze: struct {.\{-}}$')
|
||||
endif
|
||||
|
||||
if name != ''
|
||||
setlocal modifiable
|
||||
let not_open = getline(line('.')+1) !~ '^ '
|
||||
let l = line('.')
|
||||
call s:delete_expands()
|
||||
|
||||
if not_open
|
||||
call append(l, split(s:eval(name), "\n")[1:])
|
||||
endif
|
||||
silent! exe 'norm!' l.'G'
|
||||
setlocal nomodifiable
|
||||
return
|
||||
endif
|
||||
|
||||
" Expand maps
|
||||
let m = matchlist(getline('.'), '^[^:]\+\ze: map.\{-}\[\(\d\+\)\]$')
|
||||
if len(m) > 0 && m[1] != ''
|
||||
setlocal modifiable
|
||||
let not_open = getline(line('.')+1) !~ '^ '
|
||||
let l = line('.')
|
||||
call s:delete_expands()
|
||||
if not_open
|
||||
" TODO: Not sure how to do this yet... Need to get keys of the map.
|
||||
" let vs = ''
|
||||
" for i in range(0, min([10, m[1]-1]))
|
||||
" let vs .= ' ' . s:eval(printf("%s[%s]", m[0], ))
|
||||
" endfor
|
||||
" call append(l, split(vs, "\n"))
|
||||
endif
|
||||
|
||||
silent! exe 'norm!' l.'G'
|
||||
setlocal nomodifiable
|
||||
return
|
||||
endif
|
||||
|
||||
" Expand string.
|
||||
let m = matchlist(getline('.'), '^\([^:]\+\)\ze: \(string\)\[\([0-9]\+\)\]\(: .\{-}\)\?$')
|
||||
if len(m) > 0 && m[1] != ''
|
||||
setlocal modifiable
|
||||
let not_open = getline(line('.')+1) !~ '^ '
|
||||
let l = line('.')
|
||||
call s:delete_expands()
|
||||
|
||||
if not_open
|
||||
let vs = ''
|
||||
for i in range(0, min([10, m[3]-1]))
|
||||
let vs .= ' ' . s:eval(m[1] . '[' . i . ']')
|
||||
endfor
|
||||
call append(l, split(vs, "\n"))
|
||||
endif
|
||||
|
||||
silent! exe 'norm!' l.'G'
|
||||
setlocal nomodifiable
|
||||
return
|
||||
endif
|
||||
|
||||
" Expand slice.
|
||||
let m = matchlist(getline('.'), '^\([^:]\+\)\ze: \(\[\]\w\{-}\)\[\([0-9]\+\)\]$')
|
||||
if len(m) > 0 && m[1] != ''
|
||||
setlocal modifiable
|
||||
let not_open = getline(line('.')+1) !~ '^ '
|
||||
let l = line('.')
|
||||
call s:delete_expands()
|
||||
|
||||
if not_open
|
||||
let vs = ''
|
||||
for i in range(0, min([10, m[3]-1]))
|
||||
let vs .= ' ' . s:eval(m[1] . '[' . i . ']')
|
||||
endfor
|
||||
call append(l, split(vs, "\n"))
|
||||
endif
|
||||
silent! exe 'norm!' l.'G'
|
||||
setlocal nomodifiable
|
||||
return
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:start_cb(ch, json) abort
|
||||
let res = json_decode(a:json)
|
||||
if type(res) == v:t_dict && has_key(res, 'error') && !empty(res.error)
|
||||
throw res.error
|
||||
endif
|
||||
if empty(res) || !has_key(res, 'result')
|
||||
return
|
||||
endif
|
||||
for bt in res.result.Breakpoints
|
||||
if bt.id >= 0
|
||||
let s:state['breakpoint'][bt.id] = bt
|
||||
exe 'sign place '. bt.id .' line=' . bt.line . ' name=godebugbreakpoint file=' . bt.file
|
||||
endif
|
||||
endfor
|
||||
|
||||
let oldbuf = bufnr('%')
|
||||
silent! only!
|
||||
|
||||
let winnum = bufwinnr(bufnr('__GODEBUG_STACKTRACE__'))
|
||||
if winnum != -1
|
||||
return
|
||||
endif
|
||||
|
||||
if exists('g:go_debug_windows["stack"]') && g:go_debug_windows['stack'] != ''
|
||||
exe 'silent ' . g:go_debug_windows['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 exists('g:go_debug_windows["out"]') && g:go_debug_windows['out'] != ''
|
||||
exe 'silent ' . g:go_debug_windows['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 exists('g:go_debug_windows["vars"]') && g:go_debug_windows['vars'] != ''
|
||||
exe 'silent ' . g:go_debug_windows['vars']
|
||||
silent file `='__GODEBUG_VARIABLES__'`
|
||||
setlocal buftype=nofile bufhidden=wipe nomodified nobuflisted noswapfile nowrap nonumber nocursorline
|
||||
setlocal filetype=godebugvariables
|
||||
call append(0, ["# Local Variables", "", "# Function Arguments"])
|
||||
nmap <buffer> <silent> <cr> :<c-u>call <SID>expand_var()<cr>
|
||||
nmap <buffer> q <Plug>(go-debug-stop)
|
||||
endif
|
||||
|
||||
silent! delcommand GoDebugStart
|
||||
silent! delcommand GoDebugTest
|
||||
command! -nargs=0 GoDebugContinue call go#debug#Stack('continue')
|
||||
command! -nargs=0 GoDebugNext call go#debug#Stack('next')
|
||||
command! -nargs=0 GoDebugStep call go#debug#Stack('step')
|
||||
command! -nargs=0 GoDebugStepOut call go#debug#Stack('stepOut')
|
||||
command! -nargs=0 GoDebugRestart call go#debug#Restart()
|
||||
command! -nargs=0 GoDebugStop call go#debug#Stop()
|
||||
command! -nargs=* GoDebugSet call go#debug#Set(<f-args>)
|
||||
command! -nargs=1 GoDebugPrint call go#debug#Print(<q-args>)
|
||||
|
||||
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-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>
|
||||
|
||||
nmap <F5> <Plug>(go-debug-continue)
|
||||
nmap <F6> <Plug>(go-debug-print)
|
||||
nmap <F9> <Plug>(go-debug-breakpoint)
|
||||
nmap <F10> <Plug>(go-debug-next)
|
||||
nmap <F11> <Plug>(go-debug-step)
|
||||
|
||||
set balloonexpr=go#debug#BalloonExpr()
|
||||
set ballooneval
|
||||
|
||||
exe bufwinnr(oldbuf) 'wincmd w'
|
||||
endfunction
|
||||
|
||||
function! s:err_cb(ch, msg) abort
|
||||
call go#util#EchoError(a:msg)
|
||||
let s:state['message'] += [a:msg]
|
||||
endfunction
|
||||
|
||||
function! s:out_cb(ch, msg) abort
|
||||
call go#util#EchoProgress(a:msg)
|
||||
let s:state['message'] += [a:msg]
|
||||
|
||||
" TODO: why do this in this callback?
|
||||
if stridx(a:msg, g:go_debug_address) != -1
|
||||
call ch_setoptions(a:ch, {
|
||||
\ 'out_cb': function('s:logger', ['OUT: ']),
|
||||
\ 'err_cb': function('s:logger', ['ERR: ']),
|
||||
\})
|
||||
|
||||
" Tell dlv about the breakpoints that the user added before delve started.
|
||||
let l:breaks = copy(s:state.breakpoint)
|
||||
let s:state['breakpoint'] = {}
|
||||
for l:bt in values(l:breaks)
|
||||
call go#debug#Breakpoint(bt.line)
|
||||
endfor
|
||||
|
||||
call s:call_jsonrpc('RPCServer.ListBreakpoints', function('s:start_cb'))
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Start the debug mode. The first argument is the package name to compile and
|
||||
" debug, anything else will be passed to the running program.
|
||||
function! go#debug#Start(is_test, ...) abort
|
||||
if has('nvim')
|
||||
call go#util#EchoError('This feature only works in Vim for now; Neovim is not (yet) supported. Sorry :-(')
|
||||
return
|
||||
endif
|
||||
if !go#util#has_job()
|
||||
call go#util#EchoError('This feature requires Vim 8.0.0087 or newer with +job.')
|
||||
return
|
||||
endif
|
||||
|
||||
" It's already running.
|
||||
if has_key(s:state, 'job') && job_status(s:state['job']) == 'run'
|
||||
return
|
||||
endif
|
||||
|
||||
let s:start_args = a:000
|
||||
|
||||
if go#util#HasDebug('debugger-state')
|
||||
let g:go_debug_diag = s:state
|
||||
endif
|
||||
|
||||
" cd in to test directory; this is also what running "go test" does.
|
||||
if a:is_test
|
||||
lcd %:p:h
|
||||
endif
|
||||
|
||||
let s:state.is_test = a:is_test
|
||||
|
||||
let dlv = go#path#CheckBinPath("dlv")
|
||||
if empty(dlv)
|
||||
return
|
||||
endif
|
||||
|
||||
try
|
||||
if len(a:000) > 0
|
||||
let l:pkgname = a:1
|
||||
" Expand .; otherwise this won't work from a tmp dir.
|
||||
if l:pkgname[0] == '.'
|
||||
let l:pkgname = go#package#FromPath(getcwd()) . l:pkgname[1:]
|
||||
endif
|
||||
else
|
||||
let l:pkgname = go#package#FromPath(getcwd())
|
||||
endif
|
||||
|
||||
let l:args = []
|
||||
if len(a:000) > 1
|
||||
let l:args = ['--'] + a:000[1:]
|
||||
endif
|
||||
|
||||
let l:cmd = [
|
||||
\ dlv,
|
||||
\ (a:is_test ? 'test' : 'debug'),
|
||||
\ '--output', tempname(),
|
||||
\ '--headless',
|
||||
\ '--api-version', '2',
|
||||
\ '--log',
|
||||
\ '--listen', g:go_debug_address,
|
||||
\ '--accept-multiclient',
|
||||
\]
|
||||
if get(g:, 'go_build_tags', '') isnot ''
|
||||
let l:cmd += ['--build-flags', '--tags=' . g:go_build_tags]
|
||||
endif
|
||||
let l:cmd += l:args
|
||||
|
||||
call go#util#EchoProgress('Starting GoDebug...')
|
||||
let s:state['message'] = []
|
||||
let s:state['job'] = job_start(l:cmd, {
|
||||
\ 'out_cb': function('s:out_cb'),
|
||||
\ 'err_cb': function('s:err_cb'),
|
||||
\ 'exit_cb': function('s:exit'),
|
||||
\ 'stoponexit': 'kill',
|
||||
\})
|
||||
catch
|
||||
call go#util#EchoError(v:exception)
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
" Translate a reflect kind constant to a human string.
|
||||
function! s:reflect_kind(k)
|
||||
" Kind constants from Go's reflect package.
|
||||
return [
|
||||
\ 'Invalid Kind',
|
||||
\ 'Bool',
|
||||
\ 'Int',
|
||||
\ 'Int8',
|
||||
\ 'Int16',
|
||||
\ 'Int32',
|
||||
\ 'Int64',
|
||||
\ 'Uint',
|
||||
\ 'Uint8',
|
||||
\ 'Uint16',
|
||||
\ 'Uint32',
|
||||
\ 'Uint64',
|
||||
\ 'Uintptr',
|
||||
\ 'Float32',
|
||||
\ 'Float64',
|
||||
\ 'Complex64',
|
||||
\ 'Complex128',
|
||||
\ 'Array',
|
||||
\ 'Chan',
|
||||
\ 'Func',
|
||||
\ 'Interface',
|
||||
\ 'Map',
|
||||
\ 'Ptr',
|
||||
\ 'Slice',
|
||||
\ 'String',
|
||||
\ 'Struct',
|
||||
\ 'UnsafePointer',
|
||||
\ ][a:k]
|
||||
endfunction
|
||||
|
||||
function! s:eval_tree(var, nest) abort
|
||||
if a:var.name =~ '^\~'
|
||||
return ''
|
||||
endif
|
||||
let nest = a:nest
|
||||
let v = ''
|
||||
let kind = s:reflect_kind(a:var.kind)
|
||||
if !empty(a:var.name)
|
||||
let v .= repeat(' ', nest) . a:var.name . ': '
|
||||
|
||||
if kind == 'Bool'
|
||||
let v .= printf("%s\n", a:var.value)
|
||||
|
||||
elseif kind == 'Struct'
|
||||
" Anonymous struct
|
||||
if a:var.type[:8] == 'struct { '
|
||||
let v .= printf("%s\n", a:var.type)
|
||||
else
|
||||
let v .= printf("%s{...}\n", a:var.type)
|
||||
endif
|
||||
|
||||
elseif kind == 'String'
|
||||
let v .= printf("%s[%d]%s\n", a:var.type, a:var.len,
|
||||
\ len(a:var.value) > 0 ? ': ' . a:var.value : '')
|
||||
|
||||
elseif kind == 'Slice' || kind == 'String' || kind == 'Map' || kind == 'Array'
|
||||
let v .= printf("%s[%d]\n", a:var.type, a:var.len)
|
||||
|
||||
elseif kind == 'Chan' || kind == 'Func' || kind == 'Interface'
|
||||
let v .= printf("%s\n", a:var.type)
|
||||
|
||||
elseif kind == 'Ptr'
|
||||
" TODO: We can do something more useful here.
|
||||
let v .= printf("%s\n", a:var.type)
|
||||
|
||||
elseif kind == 'Complex64' || kind == 'Complex128'
|
||||
let v .= printf("%s%s\n", a:var.type, a:var.value)
|
||||
|
||||
" Int, Float
|
||||
else
|
||||
let v .= printf("%s(%s)\n", a:var.type, a:var.value)
|
||||
endif
|
||||
else
|
||||
let nest -= 1
|
||||
endif
|
||||
|
||||
if index(['Chan', 'Complex64', 'Complex128'], kind) == -1 && a:var.type != 'error'
|
||||
for c in a:var.children
|
||||
let v .= s:eval_tree(c, nest+1)
|
||||
endfor
|
||||
endif
|
||||
return v
|
||||
endfunction
|
||||
|
||||
function! s:eval(arg) abort
|
||||
try
|
||||
let res = s:call_jsonrpc('RPCServer.State')
|
||||
let goroutineID = res.result.State.currentThread.goroutineID
|
||||
let res = s:call_jsonrpc('RPCServer.Eval', {
|
||||
\ 'expr': a:arg,
|
||||
\ 'scope': {'GoroutineID': goroutineID}
|
||||
\ })
|
||||
return s:eval_tree(res.result.Variable, 0)
|
||||
catch
|
||||
call go#util#EchoError(v:exception)
|
||||
return ''
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! go#debug#BalloonExpr() abort
|
||||
silent! let l:v = s:eval(v:beval_text)
|
||||
return l:v
|
||||
endfunction
|
||||
|
||||
function! go#debug#Print(arg) abort
|
||||
try
|
||||
echo substitute(s:eval(a:arg), "\n$", "", 0)
|
||||
catch
|
||||
call go#util#EchoError(v:exception)
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! s:update_variables() abort
|
||||
" FollowPointers requests pointers to be automatically dereferenced.
|
||||
" MaxVariableRecurse is how far to recurse when evaluating nested types.
|
||||
" MaxStringLen is the maximum number of bytes read from a string
|
||||
" 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()},
|
||||
\ 'cfg': {'MaxStringLen': 20, 'MaxArrayValues': 20}
|
||||
\ }
|
||||
|
||||
try
|
||||
let res = s:call_jsonrpc('RPCServer.ListLocalVars', l:cfg)
|
||||
let s:state['localVars'] = res.result['Variables']
|
||||
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']
|
||||
catch
|
||||
call go#util#EchoError(v:exception)
|
||||
endtry
|
||||
|
||||
call s:show_variables()
|
||||
endfunction
|
||||
|
||||
function! go#debug#Set(symbol, value) abort
|
||||
try
|
||||
let res = s:call_jsonrpc('RPCServer.State')
|
||||
let goroutineID = res.result.State.currentThread.goroutineID
|
||||
call s:call_jsonrpc('RPCServer.Set', {
|
||||
\ 'symbol': a:symbol,
|
||||
\ 'value': a:value,
|
||||
\ 'scope': {'GoroutineID': goroutineID}
|
||||
\ })
|
||||
catch
|
||||
call go#util#EchoError(v:exception)
|
||||
endtry
|
||||
|
||||
call s:update_variables()
|
||||
endfunction
|
||||
|
||||
function! s:update_stacktrace() abort
|
||||
try
|
||||
let res = s:call_jsonrpc('RPCServer.Stacktrace', {'id': s:groutineID(), 'depth': 5})
|
||||
call s:show_stacktrace(res)
|
||||
catch
|
||||
call go#util#EchoError(v:exception)
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! s:stack_cb(ch, json) abort
|
||||
let s:stack_name = ''
|
||||
let res = json_decode(a:json)
|
||||
if type(res) == v:t_dict && has_key(res, 'error') && !empty(res.error)
|
||||
call go#util#EchoError(res.error)
|
||||
call s:clearState()
|
||||
call go#debug#Restart()
|
||||
return
|
||||
endif
|
||||
|
||||
if empty(res) || !has_key(res, 'result')
|
||||
return
|
||||
endif
|
||||
call s:update_breakpoint(res)
|
||||
call s:update_stacktrace()
|
||||
call s:update_variables()
|
||||
endfunction
|
||||
|
||||
" Send a command to change the cursor location to Delve.
|
||||
"
|
||||
" a:name must be one of continue, next, step, or stepOut.
|
||||
function! go#debug#Stack(name) abort
|
||||
let l:name = a:name
|
||||
|
||||
" Run continue if the program hasn't started yet.
|
||||
if s:state.running is 0
|
||||
let s:state.running = 1
|
||||
let l:name = 'continue'
|
||||
endif
|
||||
|
||||
" Add a breakpoint to the main.Main if the user didn't define any.
|
||||
if len(s:state['breakpoint']) is 0
|
||||
if go#debug#Breakpoint() isnot 0
|
||||
let s:state.running = 0
|
||||
return
|
||||
endif
|
||||
endif
|
||||
|
||||
try
|
||||
" TODO: document why this is needed.
|
||||
if l:name is# 'next' && get(s:, 'stack_name', '') is# 'next'
|
||||
call s:call_jsonrpc('RPCServer.CancelNext')
|
||||
endif
|
||||
let s:stack_name = l:name
|
||||
call s:call_jsonrpc('RPCServer.Command', function('s:stack_cb'), {'name': l:name})
|
||||
catch
|
||||
call go#util#EchoError(v:exception)
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! go#debug#Restart() abort
|
||||
try
|
||||
call job_stop(s:state['job'])
|
||||
while has_key(s:state, 'job') && job_status(s:state['job']) is# 'run'
|
||||
sleep 50m
|
||||
endwhile
|
||||
|
||||
let l:breaks = s:state['breakpoint']
|
||||
let s:state = {
|
||||
\ 'rpcid': 1,
|
||||
\ 'running': 0,
|
||||
\ 'breakpoint': {},
|
||||
\ 'currentThread': {},
|
||||
\ 'localVars': {},
|
||||
\ 'functionArgs': {},
|
||||
\ 'message': [],
|
||||
\}
|
||||
|
||||
" Preserve breakpoints.
|
||||
for bt in values(l:breaks)
|
||||
" TODO: should use correct filename
|
||||
exe 'sign unplace '. bt.id .' file=' . bt.file
|
||||
call go#debug#Breakpoint(bt.line)
|
||||
endfor
|
||||
call call('go#debug#Start', s:start_args)
|
||||
catch
|
||||
call go#util#EchoError(v:exception)
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
" Report if debugger mode is active.
|
||||
function! s:isActive()
|
||||
return len(s:state['message']) > 0
|
||||
endfunction
|
||||
|
||||
" Toggle breakpoint. Returns 0 on success and 1 on failure.
|
||||
function! go#debug#Breakpoint(...) abort
|
||||
let l:filename = fnamemodify(expand('%'), ':p:gs!\\!/!')
|
||||
|
||||
" Get line number from argument.
|
||||
if len(a:000) > 0
|
||||
let linenr = str2nr(a:1)
|
||||
if linenr is 0
|
||||
call go#util#EchoError('not a number: ' . a:1)
|
||||
return 0
|
||||
endif
|
||||
else
|
||||
let linenr = line('.')
|
||||
endif
|
||||
|
||||
try
|
||||
" Check if we already have a breakpoint for this line.
|
||||
let found = v:none
|
||||
for k in keys(s:state.breakpoint)
|
||||
let bt = s:state.breakpoint[k]
|
||||
if bt.file == l:filename && bt.line == linenr
|
||||
let found = bt
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
|
||||
" Remove breakpoint.
|
||||
if type(found) == v:t_dict
|
||||
call remove(s:state['breakpoint'], bt.id)
|
||||
exe 'sign unplace '. found.id .' file=' . found.file
|
||||
if s:isActive()
|
||||
let res = s:call_jsonrpc('RPCServer.ClearBreakpoint', {'id': found.id})
|
||||
endif
|
||||
" Add breakpoint.
|
||||
else
|
||||
if s:isActive()
|
||||
let res = s:call_jsonrpc('RPCServer.CreateBreakpoint', {'Breakpoint': {'file': l:filename, 'line': linenr}})
|
||||
let bt = res.result.Breakpoint
|
||||
exe 'sign place '. bt.id .' line=' . bt.line . ' name=godebugbreakpoint file=' . bt.file
|
||||
let s:state['breakpoint'][bt.id] = bt
|
||||
else
|
||||
let id = len(s:state['breakpoint']) + 1
|
||||
let s:state['breakpoint'][id] = {'id': id, 'file': l:filename, 'line': linenr}
|
||||
exe 'sign place '. id .' line=' . linenr . ' name=godebugbreakpoint file=' . l:filename
|
||||
endif
|
||||
endif
|
||||
catch
|
||||
call go#util#EchoError(v:exception)
|
||||
return 1
|
||||
endtry
|
||||
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
sign define godebugbreakpoint text=> texthl=GoDebugBreakpoint
|
||||
sign define godebugcurline text== linehl=GoDebugCurrent texthl=GoDebugCurrent
|
||||
|
||||
fun! s:hi()
|
||||
hi GoDebugBreakpoint term=standout ctermbg=117 ctermfg=0 guibg=#BAD4F5 guifg=Black
|
||||
hi GoDebugCurrent term=reverse ctermbg=12 ctermfg=7 guibg=DarkBlue guifg=White
|
||||
endfun
|
||||
augroup vim-go-breakpoint
|
||||
autocmd!
|
||||
autocmd ColorScheme * call s:hi()
|
||||
augroup end
|
||||
call s:hi()
|
||||
|
||||
" vim: sw=2 ts=2 et
|
@ -0,0 +1,131 @@
|
||||
func! Test_Gometa() abort
|
||||
let $GOPATH = fnameescape(fnamemodify(getcwd(), ':p')) . 'test-fixtures/lint'
|
||||
silent exe 'e ' . $GOPATH . '/src/lint/lint.go'
|
||||
|
||||
let expected = [
|
||||
\ {'lnum': 5, 'bufnr': bufnr('%')+1, 'col': 1, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': 'w', 'pattern': '', 'text': 'exported function MissingFooDoc should have comment or be unexported (golint)'}
|
||||
\ ]
|
||||
|
||||
" clear the quickfix lists
|
||||
call setqflist([], 'r')
|
||||
|
||||
" call go#lint#ToggleMetaLinterAutoSave from lint.vim so that the file will
|
||||
" be autoloaded and the default for g:go_metalinter_enabled will be set so
|
||||
" we can capture it to restore it after the test is run.
|
||||
call go#lint#ToggleMetaLinterAutoSave()
|
||||
" And restore it back to its previous value
|
||||
call go#lint#ToggleMetaLinterAutoSave()
|
||||
|
||||
let orig_go_metalinter_enabled = g:go_metalinter_enabled
|
||||
let g:go_metalinter_enabled = ['golint']
|
||||
|
||||
call go#lint#Gometa(0, $GOPATH . '/src/foo')
|
||||
|
||||
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)
|
||||
let g:go_metalinter_enabled = orig_go_metalinter_enabled
|
||||
endfunc
|
||||
|
||||
func! Test_GometaWithDisabled() abort
|
||||
let $GOPATH = fnameescape(fnamemodify(getcwd(), ':p')) . 'test-fixtures/lint'
|
||||
silent exe 'e ' . $GOPATH . '/src/lint/lint.go'
|
||||
|
||||
let expected = [
|
||||
\ {'lnum': 5, 'bufnr': bufnr('%')+1, 'col': 1, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': 'w', 'pattern': '', 'text': 'exported function MissingFooDoc should have comment or be unexported (golint)'}
|
||||
\ ]
|
||||
|
||||
" clear the quickfix lists
|
||||
call setqflist([], 'r')
|
||||
|
||||
" call go#lint#ToggleMetaLinterAutoSave from lint.vim so that the file will
|
||||
" be autoloaded and the default for g:go_metalinter_disabled will be set so
|
||||
" we can capture it to restore it after the test is run.
|
||||
call go#lint#ToggleMetaLinterAutoSave()
|
||||
" And restore it back to its previous value
|
||||
call go#lint#ToggleMetaLinterAutoSave()
|
||||
|
||||
let orig_go_metalinter_disabled = g:go_metalinter_disabled
|
||||
let g:go_metalinter_disabled = ['vet']
|
||||
|
||||
call go#lint#Gometa(0, $GOPATH . '/src/foo')
|
||||
|
||||
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)
|
||||
let g:go_metalinter_disabled = orig_go_metalinter_disabled
|
||||
endfunc
|
||||
|
||||
func! Test_GometaAutoSave() abort
|
||||
let $GOPATH = fnameescape(fnamemodify(getcwd(), ':p')) . 'test-fixtures/lint'
|
||||
silent exe 'e ' . $GOPATH . '/src/lint/lint.go'
|
||||
|
||||
let expected = [
|
||||
\ {'lnum': 5, 'bufnr': bufnr('%'), 'col': 1, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': 'w', 'pattern': '', 'text': 'exported function MissingDoc should have comment or be unexported (golint)'}
|
||||
\ ]
|
||||
|
||||
let winnr = winnr()
|
||||
|
||||
" clear the location lists
|
||||
call setloclist(l:winnr, [], 'r')
|
||||
|
||||
" call go#lint#ToggleMetaLinterAutoSave from lint.vim so that the file will
|
||||
" be autoloaded and the default for g:go_metalinter_autosave_enabled will be
|
||||
" set so we can capture it to restore it after the test is run.
|
||||
call go#lint#ToggleMetaLinterAutoSave()
|
||||
" And restore it back to its previous value
|
||||
call go#lint#ToggleMetaLinterAutoSave()
|
||||
|
||||
let orig_go_metalinter_autosave_enabled = g:go_metalinter_autosave_enabled
|
||||
let g:go_metalinter_autosave_enabled = ['golint']
|
||||
|
||||
call go#lint#Gometa(1)
|
||||
|
||||
let actual = getloclist(l:winnr)
|
||||
let start = reltime()
|
||||
while len(actual) == 0 && reltimefloat(reltime(start)) < 10
|
||||
sleep 100m
|
||||
let actual = getloclist(l:winnr)
|
||||
endwhile
|
||||
|
||||
call gotest#assert_quickfix(actual, expected)
|
||||
let g:go_metalinter_autosave_enabled = orig_go_metalinter_autosave_enabled
|
||||
endfunc
|
||||
|
||||
func! Test_Vet()
|
||||
let $GOPATH = fnameescape(fnamemodify(getcwd(), ':p')) . 'test-fixtures/lint'
|
||||
silent exe 'e ' . $GOPATH . '/src/vet/vet.go'
|
||||
compiler go
|
||||
|
||||
let expected = [
|
||||
\ {'lnum': 7, 'bufnr': bufnr('%'), 'col': 0, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'arg str for printf verb %d of wrong type: string'}
|
||||
\ ]
|
||||
|
||||
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)
|
||||
endfunc
|
||||
|
||||
" vim: sw=2 ts=2 et
|
@ -0,0 +1,50 @@
|
||||
func! Test_GoTermNewMode()
|
||||
if !has('nvim')
|
||||
return
|
||||
endif
|
||||
|
||||
try
|
||||
let l:filename = 'term/term.go'
|
||||
let l:tmp = gotest#load_fixture(l:filename)
|
||||
exe 'cd ' . l:tmp . '/src/term'
|
||||
|
||||
let expected = expand('%:p')
|
||||
|
||||
let cmd = "go run ". go#util#Shelljoin(go#tool#Files())
|
||||
|
||||
set nosplitright
|
||||
call go#term#newmode(0, cmd, '')
|
||||
let actual = expand('%:p')
|
||||
call assert_equal(actual, l:expected)
|
||||
|
||||
finally
|
||||
call delete(l:tmp, 'rf')
|
||||
endtry
|
||||
endfunc
|
||||
|
||||
func! Test_GoTermNewMode_SplitRight()
|
||||
if !has('nvim')
|
||||
return
|
||||
endif
|
||||
|
||||
try
|
||||
let l:filename = 'term/term.go'
|
||||
let l:tmp = gotest#load_fixture(l:filename)
|
||||
exe 'cd ' . l:tmp . '/src/term'
|
||||
|
||||
let expected = expand('%:p')
|
||||
|
||||
let cmd = "go run ". go#util#Shelljoin(go#tool#Files())
|
||||
|
||||
set splitright
|
||||
call go#term#newmode(0, cmd, '')
|
||||
let actual = expand('%:p')
|
||||
call assert_equal(actual, l:expected)
|
||||
|
||||
finally
|
||||
call delete(l:tmp, 'rf')
|
||||
set nosplitright
|
||||
endtry
|
||||
endfunc
|
||||
|
||||
" vim: sw=2 ts=2 et
|
@ -0,0 +1,5 @@
|
||||
package main
|
||||
|
||||
func main() {
|
||||
notafunc()
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package foo
|
||||
|
||||
import "fmt"
|
||||
|
||||
func MissingFooDoc() {
|
||||
fmt.Println("missing doc")
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package lint
|
||||
|
||||
import "fmt"
|
||||
|
||||
func MissingDoc() {
|
||||
fmt.Println("missing doc")
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package lint
|
||||
|
||||
import "fmt"
|
||||
|
||||
func AlsoMissingDoc() {
|
||||
fmt.Println("missing doc")
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
str := "hello world!"
|
||||
fmt.Printf("%d\n", str)
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package main
|
||||
|
||||
func main() {
|
||||
println("hello, world")
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package main
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestHelloWorld(t *testing.T) {
|
||||
t.Error("so long")
|
||||
|
||||
t.Run("sub", func(t *testing.T) {
|
||||
t.Error("thanks for all the fish")
|
||||
})
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
// Run a few parallel tests, all in parallel, using multiple techniques for
|
||||
// causing the test to take a while so that the stacktraces resulting from a
|
||||
// test timeout will contain several goroutines to avoid giving a false sense
|
||||
// of confidence or creating error formats that don't account for the more
|
||||
// complex scenarios that can occur with timeouts.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestSleep(t *testing.T) {
|
||||
t.Parallel()
|
||||
time.Sleep(15 * time.Second)
|
||||
t.Log("expected panic if run with timeout < 15s")
|
||||
}
|
||||
|
||||
func TestRunning(t *testing.T) {
|
||||
t.Parallel()
|
||||
c := time.After(15 * time.Second)
|
||||
Loop:
|
||||
for {
|
||||
select {
|
||||
case <-c:
|
||||
break Loop
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
t.Log("expected panic if run with timeout < 15s")
|
||||
}
|
||||
|
||||
func TestRunningAlso(t *testing.T) {
|
||||
t.Parallel()
|
||||
c := time.After(15 * time.Second)
|
||||
Loop:
|
||||
for {
|
||||
select {
|
||||
case <-c:
|
||||
break Loop
|
||||
default:
|
||||
}
|
||||
}
|
||||
t.Log("expected panic if run with timeout < 15s")
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
if exists("b:current_syntax")
|
||||
finish
|
||||
endif
|
||||
|
||||
syn match godebugOutputErr '^ERR:.*'
|
||||
syn match godebugOutputOut '^OUT:.*'
|
||||
|
||||
let b:current_syntax = "godebugoutput"
|
||||
|
||||
hi def link godebugOutputErr Comment
|
||||
hi def link godebugOutputOut Normal
|
||||
|
||||
" vim: sw=2 ts=2 et
|
@ -0,0 +1,11 @@
|
||||
if exists("b:current_syntax")
|
||||
finish
|
||||
endif
|
||||
|
||||
syn match godebugStacktrace '^\S\+'
|
||||
|
||||
let b:current_syntax = "godebugoutput"
|
||||
|
||||
hi def link godebugStacktrace SpecialKey
|
||||
|
||||
" vim: sw=2 ts=2 et
|
@ -0,0 +1,23 @@
|
||||
if exists("b:current_syntax")
|
||||
finish
|
||||
endif
|
||||
|
||||
syn match godebugTitle '^#.*'
|
||||
syn match godebugVariables '^\s*\S\+\ze:'
|
||||
|
||||
syn keyword goType chan map bool string error
|
||||
syn keyword goSignedInts int int8 int16 int32 int64 rune
|
||||
syn keyword goUnsignedInts byte uint uint8 uint16 uint32 uint64 uintptr
|
||||
syn keyword goFloats float32 float64
|
||||
syn keyword goComplexes complex64 complex128
|
||||
|
||||
syn keyword goBoolean true false
|
||||
|
||||
let b:current_syntax = "godebugvariables"
|
||||
|
||||
hi def link godebugTitle Underlined
|
||||
hi def link godebugVariables Statement
|
||||
hi def link goType Type
|
||||
hi def link goBoolean Boolean
|
||||
|
||||
" vim: sw=2 ts=2 et
|
Loading…
Reference in New Issue