Skip to content

Commit c27eac1

Browse files
committed
debug: add :GoDebugAttach
Add :GoDebugAttach to be able to attach to a running process. Closes #1758
1 parent 188884f commit c27eac1

File tree

3 files changed

+68
-34
lines changed

3 files changed

+68
-34
lines changed

autoload/go/debug.vim

+53-30
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ if !exists('s:state')
1313
\ 'functionArgs': {},
1414
\ 'message': [],
1515
\ 'resultHandlers': {},
16+
\ 'kill_on_detach': v:true,
1617
\ }
1718

1819
if go#util#HasDebug('debugger-state')
@@ -252,7 +253,7 @@ function! s:clearState() abort
252253
endfunction
253254

254255
function! s:stop() abort
255-
call s:call_jsonrpc(function('s:noop'), 'RPCServer.Detach', {'kill': v:true})
256+
call s:call_jsonrpc(function('s:noop'), 'RPCServer.Detach', {'kill': s:state['kill_on_detach']})
256257

257258
if has_key(s:state, 'job')
258259
call go#job#Wait(s:state['job'])
@@ -281,6 +282,7 @@ function! go#debug#Stop() abort
281282
endfor
282283
command! -nargs=* -complete=customlist,go#package#Complete GoDebugStart call go#debug#Start(0, <f-args>)
283284
command! -nargs=* -complete=customlist,go#package#Complete GoDebugTest call go#debug#Start(1, <f-args>)
285+
command! -nargs=1 GoDebugAttach call go#debug#Start(2, <f-args>)
284286
command! -nargs=? GoDebugBreakpoint call go#debug#Breakpoint(<f-args>)
285287

286288
" Remove all mappings.
@@ -689,7 +691,7 @@ endfunction
689691

690692
" Start the debug mode. The first argument is the package name to compile and
691693
" debug, anything else will be passed to the running program.
692-
function! go#debug#Start(is_test, ...) abort
694+
function! go#debug#Start(mode, ...) abort
693695
call go#cmd#autowrite()
694696

695697
if !go#util#has_job()
@@ -702,7 +704,7 @@ function! go#debug#Start(is_test, ...) abort
702704
return s:state['job']
703705
endif
704706

705-
let s:start_args = [a:is_test] + a:000
707+
let s:start_args = [a:mode] + a:000
706708

707709
if go#util#HasDebug('debugger-state')
708710
call go#config#SetDebugDiag(s:state)
@@ -714,33 +716,19 @@ function! go#debug#Start(is_test, ...) abort
714716
endif
715717

716718
try
717-
let l:cmd = [
718-
\ dlv,
719-
\ (a:is_test ? 'test' : 'debug'),
720-
\]
721-
722-
" append the package when it's given.
723-
if len(a:000) > 0
724-
let l:pkgname = a:1
725-
if l:pkgname[0] == '.'
726-
let l:pkgabspath = fnamemodify(l:pkgname, ':p')
727-
728-
let l:cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : 'cd'
729-
let l:dir = getcwd()
730-
execute l:cd fnameescape(expand('%:p:h'))
731-
732-
try
733-
let l:pkgname = go#package#FromPath(l:pkgabspath)
734-
if type(l:pkgname) == type(0)
735-
call go#util#EchoError('could not determine package name')
736-
return
737-
endif
738-
finally
739-
execute l:cd fnameescape(l:dir)
740-
endtry
741-
endif
742719

743-
let l:cmd += [l:pkgname]
720+
let l:cmd = [dlv]
721+
722+
let s:state['kill_on_detach'] = v:true
723+
if a:mode is 0
724+
let l:cmd = add(dlv, 'debug')
725+
let l:cmd = extend(l:cmd, s:package(a:000))
726+
elseif a:mode is 1
727+
let l:cmd = add(dlv, 'test')
728+
let l:cmd = extend(l:cmd, s:package(a:000))
729+
elseif a:mode is 2
730+
let l:cmd = add(dlv, 'attach', a:1)
731+
let s:state['kill_on_detach'] = v:false
744732
endif
745733

746734
let l:cmd += [
@@ -782,7 +770,41 @@ function! go#debug#Start(is_test, ...) abort
782770
return s:state['job']
783771
endfunction
784772

785-
" Translate a reflect kind constant to a human string.
773+
" s:package returns the import path of package name of a :GoDebug(Start|Test)
774+
" call as a list so that the package can be appended to a command list using
775+
" extend(). args is expected to be a (potentially empty_ list. The first
776+
" element in args (if there are any) is expected to be a package path. An
777+
" emnpty list is returned when either args is an empty list or the import path
778+
" cannot be determined.
779+
function! s:package(args)
780+
if len(a:args) == 0
781+
return []
782+
endif
783+
784+
" append the package when it's given.
785+
let l:pkgname = a:args[0]
786+
if l:pkgname[0] == '.'
787+
let l:pkgabspath = fnamemodify(l:pkgname, ':p')
788+
789+
let l:cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : 'cd'
790+
let l:dir = getcwd()
791+
l:dir = go#util#Chdir(fnameescape(expand('%:p:h')))
792+
793+
try
794+
let l:pkgname = go#package#FromPath(l:pkgabspath)
795+
if type(l:pkgname) == type(0)
796+
call go#util#EchoError('could not determine package name')
797+
return []
798+
endif
799+
finally
800+
call go#util#Chdir(fnameescape(l:dir))
801+
endtry
802+
endif
803+
804+
return [l:pkgname]
805+
endfunction
806+
807+
" Translate a reflect kind constant to a human string.
786808
function! s:reflect_kind(k)
787809
" Kind constants from Go's reflect package.
788810
return [
@@ -1210,6 +1232,7 @@ function! go#debug#Restart() abort
12101232
\ 'functionArgs': {},
12111233
\ 'message': [],
12121234
\ 'resultHandlers': {},
1235+
\ 'kill_on_detach': s:state['kill_on_detach'],
12131236
\ }
12141237

12151238
call call('go#debug#Start', s:start_args)

doc/vim-go.txt

+14-4
Original file line numberDiff line numberDiff line change
@@ -2258,10 +2258,20 @@ the `dlv` process, or |:GoDebugRestart| to recompile the code.
22582258
*go-debug-commands*
22592259
DEBUGGER COMMANDS~
22602260

2261-
Only |:GoDebugStart|, `:GoDebugTest`, and |:GoDebugBreakpoint| are available
2262-
by default. `:GoDebugContinue` becomes available after running `:GoDebugStart`
2263-
or `:GoDebugTest`. The rest of the commands and mappings become available
2264-
after executing `:GoDebugContinue`.
2261+
Only |:GoDebugAttach|, |:GoDebugStart|, `:GoDebugTest`, and |:GoDebugBreakpoint| are available
2262+
by default. `:GoDebugContinue` becomes available after running
2263+
|`:GoDebugAttach|, `:GoDebugStart` or `:GoDebugTest`. The rest of the commands
2264+
and mappings become available after executing `:GoDebugContinue`.
2265+
2266+
*:GoDebugAttach*
2267+
:GoDebugAttach pid
2268+
2269+
Start the debug mode for pid; this does several things:
2270+
2271+
* Setup the debug windows according to |'g:go_debug_windows'|.
2272+
* Make the `:GoDebug*` commands and `(go-debug-*)` mappings available.
2273+
2274+
Use |:GoDebugStop| to stop `dlv` and exit debugging mode.
22652275

22662276
*:GoDebugStart*
22672277
:GoDebugStart [pkg] [program-args]

ftplugin/go/commands.vim

+1
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ command! -nargs=0 GoFillStruct call go#fillstruct#FillStruct()
107107
if !exists(':GoDebugStart')
108108
command! -nargs=* -complete=customlist,go#package#Complete GoDebugStart call go#debug#Start(0, <f-args>)
109109
command! -nargs=* -complete=customlist,go#package#Complete GoDebugTest call go#debug#Start(1, <f-args>)
110+
command! -nargs=1 GoDebugAttach call go#debug#Start(2, <f-args>)
110111
command! -nargs=? GoDebugBreakpoint call go#debug#Breakpoint(<f-args>)
111112
endif
112113

0 commit comments

Comments
 (0)