diff --git a/autoload/go/debug.vim b/autoload/go/debug.vim index abe7144fff..62b9318ec6 100644 --- a/autoload/go/debug.vim +++ b/autoload/go/debug.vim @@ -282,6 +282,7 @@ function! go#debug#Stop() abort endfor command! -nargs=* -complete=customlist,go#package#Complete GoDebugStart call go#debug#Start('debug', ) command! -nargs=* -complete=customlist,go#package#Complete GoDebugTest call go#debug#Start('test', ) + command! -nargs=* GoDebugTestFunc call go#debug#TestFunc() command! -nargs=1 GoDebugAttach call go#debug#Start('attach', ) command! -nargs=? GoDebugBreakpoint call go#debug#Breakpoint() @@ -689,6 +690,15 @@ function! s:handleRPCResult(resp) abort endtry endfunction +function! go#debug#TestFunc(...) abort + let l:test = go#util#TestName() + if l:test is '' + call go#util#Warn("vim-go: [debug] no test found immediate to cursor") + return + endif + call call('go#debug#Start', extend(['test', '.', '-test.run', printf('%s$', l:test)], a:000)) +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(mode, ...) abort @@ -770,9 +780,9 @@ endfunction " s:package returns the import path of package name of a :GoDebug(Start|Test) " call as a list so that the package can be appended to a command list using -" extend(). args is expected to be a (potentially empty_ list. The first +" extend(). args is expected to be a (potentially empty) list. The first " element in args (if there are any) is expected to be a package path. An -" emnpty list is returned when either args is an empty list or the import path +" empty list is returned when either args is an empty list or the import path " cannot be determined. function! s:package(args) if len(a:args) == 0 diff --git a/autoload/go/test.vim b/autoload/go/test.vim index 89dcda6bd9..8434575ccd 100644 --- a/autoload/go/test.vim +++ b/autoload/go/test.vim @@ -106,24 +106,12 @@ endfunction " Testfunc runs a single test that surrounds the current cursor position. " Arguments are passed to the `go test` command. function! go#test#Func(bang, ...) abort - " search flags legend (used only) - " 'b' search backward instead of forward - " 'c' accept a match at the cursor position - " 'n' do Not move the cursor - " 'W' don't wrap around the end of the file - " - " for the full list - " :help search - let test = search('func \(Test\|Example\)', "bcnW") - - if test == 0 - echo "vim-go: [test] no test found immediate to cursor" + let l:test = go#util#TestName() + if l:test is '' + call go#util#EchoWarning("[test] no test found immediate to cursor") return - end - - let line = getline(test) - let name = split(split(line, " ")[1], "(")[0] - let args = [a:bang, 0, "-run", name . "$"] + endif + let args = [a:bang, 0, "-run", l:test . "$"] if a:0 call extend(args, a:000) diff --git a/autoload/go/util.vim b/autoload/go/util.vim index d1cc48d35c..cda0d4c548 100644 --- a/autoload/go/util.vim +++ b/autoload/go/util.vim @@ -710,6 +710,27 @@ function! go#util#Chdir(dir) abort return chdir(a:dir) endfunction +" go#util#TestName returns the name of the test function that preceeds the +" cursor. +function go#util#TestName() abort + " search flags legend (used only) + " 'b' search backward instead of forward + " 'c' accept a match at the cursor position + " 'n' do Not move the cursor + " 'W' don't wrap around the end of the file + " + " for the full list + " :help search + let l:line = search('func \(Test\|Example\)', "bcnW") + + if l:line == 0 + return '' + endif + + let l:decl = getline(l:line) + return split(split(l:decl, " ")[1], "(")[0] +endfunction + " restore Vi compatibility settings let &cpo = s:cpo_save unlet s:cpo_save diff --git a/doc/vim-go.txt b/doc/vim-go.txt index 14e8062a3c..de1738d524 100644 --- a/doc/vim-go.txt +++ b/doc/vim-go.txt @@ -2321,6 +2321,14 @@ The rest of the commands and mappings become available after executing Use `-test.flag` to pass flags to `go test` when debugging a test; for example `-test.v` or `-test.run TestFoo` + *:GoDebugTestFunc* +:GoDebugTestFunc [expand] + + Behaves the same as |:GoDebugTest| and implicitly adds `-test.run` to run + the nearest test or example function (i.e the nearest function declaration + that matches `func Test` or `func Example`) at or previous to the cursor. + Search will not wrap around when at the top of the file. + *:GoDebugRestart* :GoDebugRestart diff --git a/ftplugin/go/commands.vim b/ftplugin/go/commands.vim index ebc911b8d8..19487d0970 100644 --- a/ftplugin/go/commands.vim +++ b/ftplugin/go/commands.vim @@ -107,6 +107,7 @@ command! -nargs=0 GoFillStruct call go#fillstruct#FillStruct() if !exists(':GoDebugStart') command! -nargs=* -complete=customlist,go#package#Complete GoDebugStart call go#debug#Start('debug', ) command! -nargs=* -complete=customlist,go#package#Complete GoDebugTest call go#debug#Start('test', ) + command! -nargs=* GoDebugTestFunc call go#debug#TestFunc() command! -nargs=1 GoDebugAttach call go#debug#Start('attach', ) command! -nargs=? GoDebugBreakpoint call go#debug#Breakpoint() endif