Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat/#2338: support debug multi goroutine #2463

Merged
merged 10 commits into from
Sep 17, 2019
7 changes: 4 additions & 3 deletions autoload/go/config.vim
Original file line number Diff line number Diff line change
Expand Up @@ -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',
\ 'goroutines': 'split 60vnew',
\ 'out': 'botright 100new',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did you mean to change this from 10 to 100?

\ 'vars': 'leftabove 40vnew',
\ 'stack': 'leftabove 40vnew',
\ }
\ )

Expand Down
106 changes: 104 additions & 2 deletions autoload/go/debug.vim
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,7 @@ endfunction

function! s:start_cb() abort
let l:winid = win_getid()
let l:goroutine_win_id=0
silent! only!

let winnum = bufwinnr(bufnr('__GODEBUG_STACKTRACE__'))
Expand All @@ -435,6 +436,15 @@ function! s:start_cb() abort
nmap <buffer> q <Plug>(go-debug-stop)
endif

if has_key(debugwindows, "goroutines") && debugwindows['goroutines'] != ''
exe 'silent ' . debugwindows['goroutines']
let l:goroutine_win_id = win_getid()
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, "vars") && debugwindows['vars'] != ''
exe 'silent ' . debugwindows['vars']
silent file `='__GODEBUG_VARIABLES__'`
Expand All @@ -445,6 +455,13 @@ function! s:start_cb() abort
nmap <buffer> q <Plug>(go-debug-stop)
endif

call win_gotoid(l:winid)
exe "resize +12"
if l:goroutine_win_id != 0
call win_gotoid(l:goroutine_win_id)
exe "resize +6"
endif
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this resize windows?


silent! delcommand GoDebugStart
silent! delcommand GoDebugTest
command! -nargs=0 GoDebugContinue call go#debug#Stack('continue')
Expand Down Expand Up @@ -771,6 +788,68 @@ function! go#debug#Print(arg) abort
endtry
endfunction

function! s:update_goroutines() abort
let l:var_win = bufwinnr(bufnr('__GODEBUG_GOROUTINES__'))
if l:var_win == -1
return
endif

let l:cur_win = bufwinnr('')
exe l:var_win 'wincmd w'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use win_gotoid instead of normal mode commands.


try
setlocal modifiable
silent %delete _

let v = []
let v += ['# Goroutines']
let l:res = s:call_jsonrpc('RPCServer.State')
let l:currentGoroutineId = 0
try
let l:currentGoroutineId = l:res["result"]["State"]["currentGoroutine"]["id"]
catch
call go#util#EchoInfo("current goroutineId not found...")
endtry
let l:res = s:call_jsonrpc('RPCServer.ListGoroutines')
let l:goroutines = l:res["result"]["Goroutines"]
if len(l:goroutines) == 0
call go#util#EchoError("No Goroutines Running Now...")
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
if l:goroutine.id == l:currentGoroutineId
let l:g = "* Goroutine " . l:goroutine.id . " - " . l:goroutineType . ": " . l:loc.file . ":" . l:loc.line . " " . l:loc.function.name . " " . " (thread: " . l:goroutine.threadID . ")"
else
let l:g = " Goroutine " . l:goroutine.id . " - " . l:goroutineType . ": " . l:loc.file . ":" . l:loc.line . " " . l:loc.function.name . " " . " (thread: " . l:goroutine.threadID . ")"
endif
let v += [l:g]
endfor

call setline(1, v)
finally
setlocal nomodifiable
exe l:cur_win 'wincmd w'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use win_gotoid

endtry
endfunction
function! s:update_variables() abort
" FollowPointers requests pointers to be automatically dereferenced.
" MaxVariableRecurse is how far to recurse when evaluating nested types.
Expand Down Expand Up @@ -832,6 +911,7 @@ function! s:stack_cb(res) abort
call s:update_breakpoint(a:res)
call s:update_stacktrace()
call s:update_variables()
call s:update_goroutines()
endfunction

" Send a command to change the cursor location to Delve.
Expand Down Expand Up @@ -861,8 +941,18 @@ 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:w = 0
while l:w < 1
if l:res.result.State.NextInProgress == v:true
let l:res = 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()
Expand Down Expand Up @@ -899,6 +989,18 @@ function! s:isActive()
return len(s:state['message']) > 0
endfunction

" Change Goroutine
function! go#debug#Goroutine() abort
let l:goroutineId = split(getline('.'), " ")[1]
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!\\!/!')
Expand Down