Compare commits
6 commits
master
...
data-break
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af57d2dbdb | ||
|
|
c2353b388d | ||
|
|
32360236ff | ||
|
|
f4831657b8 | ||
|
|
f92f2c5d93 | ||
|
|
cb0fdc7613 |
14 changed files with 320 additions and 53 deletions
|
|
@ -41,11 +41,11 @@ function! s:Enabled() abort
|
||||||
return s:enabled
|
return s:enabled
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! vimspector#Launch() abort
|
function! vimspector#Launch( ... ) abort
|
||||||
if !s:Enabled()
|
if !s:Enabled()
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
py3 _vimspector_session.Start()
|
py3 _vimspector_session.Start( *vim.eval( 'a:000' ) )
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! vimspector#LaunchWithSettings( settings ) abort
|
function! vimspector#LaunchWithSettings( settings ) abort
|
||||||
|
|
@ -220,6 +220,14 @@ function! vimspector#SetVariableValue( ... ) abort
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! vimspector#AddDataBreakpoint( ... ) abort
|
||||||
|
if !s:Enabled()
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
" TODO: how to set options?
|
||||||
|
py3 _vimspector_session.AddDataBreakpoint( {} )
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! vimspector#DeleteWatch() abort
|
function! vimspector#DeleteWatch() abort
|
||||||
if !s:Enabled()
|
if !s:Enabled()
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,28 @@ function! vimspector#internal#neopopup#HideSplash( id ) abort
|
||||||
unlet s:db[ a:id ]
|
unlet s:db[ a:id ]
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! vimspector#internal#neopopup#Confirm( confirm_id,
|
||||||
|
\ text,
|
||||||
|
\ default_value ) abort
|
||||||
|
let result = confirm( a:text, '&Yes &No &Default', 3 )
|
||||||
|
|
||||||
|
" Map the results to what popup_menu_filter would return (ok s:ConfirmCallback
|
||||||
|
" in popup.vim)
|
||||||
|
if result == 2
|
||||||
|
" No is represented as 0
|
||||||
|
let result = 0
|
||||||
|
elseif result == 0
|
||||||
|
" User pressed ESC/ctrl-c
|
||||||
|
let result = -1
|
||||||
|
elseif result == 3
|
||||||
|
" Default
|
||||||
|
let result = a:default_value
|
||||||
|
endif
|
||||||
|
|
||||||
|
py3 __import__( 'vimspector', fromlist = [ 'utils' ] ).utils.ConfirmCallback(
|
||||||
|
\ int( vim.eval( 'a:confirm_id' ) ),
|
||||||
|
\ int( vim.eval( 'result' ) ) )
|
||||||
|
endfunction
|
||||||
" Boilerplate {{{
|
" Boilerplate {{{
|
||||||
let &cpoptions=s:save_cpo
|
let &cpoptions=s:save_cpo
|
||||||
unlet s:save_cpo
|
unlet s:save_cpo
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,37 @@ function! vimspector#internal#popup#HideSplash( id ) abort
|
||||||
call popup_hide( a:id )
|
call popup_hide( a:id )
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! s:YesNoDefaultFilter( default_value, id, key ) abort
|
||||||
|
if a:key ==# "\<CR>" || a:key ==# 'D' || a:key ==# 'd'
|
||||||
|
call popup_close( a:id, a:default_value )
|
||||||
|
endif
|
||||||
|
|
||||||
|
return popup_filter_yesno( a:id, a:key )
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:ConfirmCallback( confirm_id, id, result ) abort
|
||||||
|
py3 __import__( 'vimspector', fromlist = [ 'utils' ] ).utils.ConfirmCallback(
|
||||||
|
\ int( vim.eval( 'a:confirm_id' ) ),
|
||||||
|
\ int( vim.eval( 'a:result' ) ) )
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! vimspector#internal#popup#Confirm(
|
||||||
|
\ confirm_id,
|
||||||
|
\ text,
|
||||||
|
\ default_value ) abort
|
||||||
|
let text = a:text
|
||||||
|
if type( a:text ) != v:t_list
|
||||||
|
let text = [ a:text ]
|
||||||
|
endif
|
||||||
|
|
||||||
|
call extend( text, [ '', '(Y)es (N)o (D)efault' ] )
|
||||||
|
|
||||||
|
return popup_dialog( text, {
|
||||||
|
\ 'callback': function( 's:ConfirmCallback', [ a:confirm_id ] ),
|
||||||
|
\ 'filter': function( 's:YesNoDefaultFilter', [ a:default_value ] )
|
||||||
|
\ } )
|
||||||
|
endfunction
|
||||||
|
|
||||||
" Boilerplate {{{
|
" Boilerplate {{{
|
||||||
let &cpoptions=s:save_cpo
|
let &cpoptions=s:save_cpo
|
||||||
unlet s:save_cpo
|
unlet s:save_cpo
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,8 @@ let s:mappings = get( g:, 'vimspector_enable_mappings', '' )
|
||||||
|
|
||||||
nnoremap <silent> <Plug>VimspectorContinue
|
nnoremap <silent> <Plug>VimspectorContinue
|
||||||
\ :<c-u>call vimspector#Continue()<CR>
|
\ :<c-u>call vimspector#Continue()<CR>
|
||||||
|
nnoremap <silent> <Plug>VimspectorLaunch
|
||||||
|
\ :<c-u>call vimspector#Launch( v:true )<CR>
|
||||||
nnoremap <silent> <Plug>VimspectorStop
|
nnoremap <silent> <Plug>VimspectorStop
|
||||||
\ :<c-u>call vimspector#Stop()<CR>
|
\ :<c-u>call vimspector#Stop()<CR>
|
||||||
nnoremap <silent> <Plug>VimspectorRestart
|
nnoremap <silent> <Plug>VimspectorRestart
|
||||||
|
|
@ -79,6 +81,7 @@ if s:mappings ==# 'VISUAL_STUDIO'
|
||||||
nmap <S-F11> <Plug>VimspectorStepOut
|
nmap <S-F11> <Plug>VimspectorStepOut
|
||||||
elseif s:mappings ==# 'HUMAN'
|
elseif s:mappings ==# 'HUMAN'
|
||||||
nmap <F5> <Plug>VimspectorContinue
|
nmap <F5> <Plug>VimspectorContinue
|
||||||
|
nmap <leader><F5> <Plug>VimspectorLaunch
|
||||||
nmap <F3> <Plug>VimspectorStop
|
nmap <F3> <Plug>VimspectorStop
|
||||||
nmap <F4> <Plug>VimspectorRestart
|
nmap <F4> <Plug>VimspectorRestart
|
||||||
nmap <F6> <Plug>VimspectorPause
|
nmap <F6> <Plug>VimspectorPause
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ class ProjectBreakpoints( object ):
|
||||||
self._func_breakpoints = []
|
self._func_breakpoints = []
|
||||||
self._exception_breakpoints = None
|
self._exception_breakpoints = None
|
||||||
self._configured_breakpoints = {}
|
self._configured_breakpoints = {}
|
||||||
|
self._data_breakponts = []
|
||||||
|
|
||||||
# FIXME: Remove this. Remove breakpoints nonesense from code.py
|
# FIXME: Remove this. Remove breakpoints nonesense from code.py
|
||||||
self._breakpoints_handler = None
|
self._breakpoints_handler = None
|
||||||
|
|
@ -270,6 +271,18 @@ class ProjectBreakpoints( object ):
|
||||||
|
|
||||||
# TODO: We don't really have aanything to update here, but if we're going to
|
# TODO: We don't really have aanything to update here, but if we're going to
|
||||||
# have a UI list of them we should update that at this point
|
# have a UI list of them we should update that at this point
|
||||||
|
# but note that while debugging, this is when we actually _send_ the
|
||||||
|
# breakpoints.
|
||||||
|
self.UpdateUI()
|
||||||
|
|
||||||
|
|
||||||
|
def AddDataBreakpoint( self, dataId, options ):
|
||||||
|
self._data_breakponts.append( {
|
||||||
|
'state': 'ENABLED',
|
||||||
|
'dataId': dataId,
|
||||||
|
'options': options,
|
||||||
|
} )
|
||||||
|
|
||||||
self.UpdateUI()
|
self.UpdateUI()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -402,6 +415,27 @@ class ProjectBreakpoints( object ):
|
||||||
failure_handler = response_received
|
failure_handler = response_received
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if self._data_breakponts and self._server_capabilities[
|
||||||
|
'supportsDataBreakpoints' ]:
|
||||||
|
awaiting += 1
|
||||||
|
breakpoints = []
|
||||||
|
for bp in self._data_breakponts:
|
||||||
|
if bp[ 'state' ] != 'ENABLED':
|
||||||
|
continue
|
||||||
|
data_bp = {}
|
||||||
|
data_bp.update( bp[ 'options' ] )
|
||||||
|
data_bp[ 'dataId' ] = bp[ 'dataId' ]
|
||||||
|
breakpoints.append( data_bp )
|
||||||
|
|
||||||
|
self._connection.DoRequest(
|
||||||
|
lambda msg: response_handler( None, None ),
|
||||||
|
{
|
||||||
|
'command': 'setDataBreakpoints',
|
||||||
|
'arguments': breakpoints,
|
||||||
|
},
|
||||||
|
failure_handler = response_received
|
||||||
|
)
|
||||||
|
|
||||||
if self._exception_breakpoints:
|
if self._exception_breakpoints:
|
||||||
awaiting = awaiting + 1
|
awaiting = awaiting + 1
|
||||||
self._connection.DoRequest(
|
self._connection.DoRequest(
|
||||||
|
|
@ -494,6 +528,11 @@ class ProjectBreakpoints( object ):
|
||||||
file_name,
|
file_name,
|
||||||
bp[ 'line' ] )
|
bp[ 'line' ] )
|
||||||
|
|
||||||
|
# TODO could/should we show a sign in the variables view when there's a data
|
||||||
|
# brakpoint on the variable? Not sure how best to actually do that, but
|
||||||
|
# maybe the variable view can pass that info when calling AddDataBreakpoint,
|
||||||
|
# such as the variablesReference/name
|
||||||
|
|
||||||
|
|
||||||
def _SignToLine( self, file_name, bp ):
|
def _SignToLine( self, file_name, bp ):
|
||||||
if 'sign_id' not in bp:
|
if 'sign_id' not in bp:
|
||||||
|
|
|
||||||
43
python3/vimspector/custom/java.py
Normal file
43
python3/vimspector/custom/java.py
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
# vimspector - A multi-language debugging system for Vim
|
||||||
|
# Copyright 2021 Ben Jackson
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
from vimspector.debug_session import DebugSession
|
||||||
|
from vimspector import utils
|
||||||
|
|
||||||
|
|
||||||
|
class JavaDebugAdapter( object ):
|
||||||
|
def __init__( self, debug_session: DebugSession ):
|
||||||
|
self.debug_session = debug_session
|
||||||
|
|
||||||
|
def OnEvent_hotcodereplace( self, message ):
|
||||||
|
# Hack for java debug server hot-code-replace
|
||||||
|
body = message.get( 'body' ) or {}
|
||||||
|
|
||||||
|
if body.get( 'type' ) != 'hotcodereplace':
|
||||||
|
return
|
||||||
|
|
||||||
|
if body.get( 'changeType' ) == 'BUILD_COMPLETE':
|
||||||
|
def handler( result ):
|
||||||
|
if result == 1:
|
||||||
|
self.debug_session._connection.DoRequest( None, {
|
||||||
|
'command': 'redefineClasses',
|
||||||
|
'arguments': {},
|
||||||
|
} )
|
||||||
|
|
||||||
|
utils.Confirm( self.debug_session._api_prefix,
|
||||||
|
'Code has changed, hot reload?',
|
||||||
|
handler )
|
||||||
|
elif body.get( 'message' ):
|
||||||
|
utils.UserMessage( 'Hot code replace: ' + body[ 'message' ] )
|
||||||
|
|
@ -29,14 +29,14 @@ class PendingRequest( object ):
|
||||||
|
|
||||||
|
|
||||||
class DebugAdapterConnection( object ):
|
class DebugAdapterConnection( object ):
|
||||||
def __init__( self, handler, send_func ):
|
def __init__( self, handlers, send_func ):
|
||||||
self._logger = logging.getLogger( __name__ )
|
self._logger = logging.getLogger( __name__ )
|
||||||
utils.SetUpLogging( self._logger )
|
utils.SetUpLogging( self._logger )
|
||||||
|
|
||||||
self._Write = send_func
|
self._Write = send_func
|
||||||
self._SetState( 'READ_HEADER' )
|
self._SetState( 'READ_HEADER' )
|
||||||
self._buffer = bytes()
|
self._buffer = bytes()
|
||||||
self._handler = handler
|
self._handlers = handlers
|
||||||
self._next_message_id = 0
|
self._next_message_id = 0
|
||||||
self._outstanding_requests = {}
|
self._outstanding_requests = {}
|
||||||
|
|
||||||
|
|
@ -124,7 +124,7 @@ class DebugAdapterConnection( object ):
|
||||||
|
|
||||||
def Reset( self ):
|
def Reset( self ):
|
||||||
self._Write = None
|
self._Write = None
|
||||||
self._handler = None
|
self._handlers = None
|
||||||
|
|
||||||
while self._outstanding_requests:
|
while self._outstanding_requests:
|
||||||
_, request = self._outstanding_requests.popitem()
|
_, request = self._outstanding_requests.popitem()
|
||||||
|
|
@ -237,7 +237,7 @@ class DebugAdapterConnection( object ):
|
||||||
|
|
||||||
|
|
||||||
def _OnMessageReceived( self, message ):
|
def _OnMessageReceived( self, message ):
|
||||||
if not self._handler:
|
if not self._handlers:
|
||||||
return
|
return
|
||||||
|
|
||||||
if message[ 'type' ] == 'response':
|
if message[ 'type' ] == 'response':
|
||||||
|
|
@ -270,25 +270,21 @@ class DebugAdapterConnection( object ):
|
||||||
self._logger.error( 'Request failed: {0}'.format( reason ) )
|
self._logger.error( 'Request failed: {0}'.format( reason ) )
|
||||||
if request.failure_handler:
|
if request.failure_handler:
|
||||||
request.failure_handler( reason, message )
|
request.failure_handler( reason, message )
|
||||||
elif 'OnFailure' in dir( self._handler ):
|
|
||||||
self._handler.OnFailure( reason, request.msg, message )
|
|
||||||
else:
|
else:
|
||||||
utils.UserMessage( 'Request failed: {0}'.format( reason ) )
|
for h in self._handlers:
|
||||||
|
if 'OnFailure' in dir( h ):
|
||||||
|
h.OnFailure( reason, request.msg, message )
|
||||||
|
|
||||||
elif message[ 'type' ] == 'event':
|
elif message[ 'type' ] == 'event':
|
||||||
method = 'OnEvent_' + message[ 'event' ]
|
method = 'OnEvent_' + message[ 'event' ]
|
||||||
if method in dir( self._handler ):
|
for h in self._handlers:
|
||||||
getattr( self._handler, method )( message )
|
if method in dir( h ):
|
||||||
else:
|
getattr( h, method )( message )
|
||||||
utils.UserMessage( 'Unhandled event: {0}'.format( message[ 'event' ] ),
|
|
||||||
persist = True )
|
|
||||||
elif message[ 'type' ] == 'request':
|
elif message[ 'type' ] == 'request':
|
||||||
method = 'OnRequest_' + message[ 'command' ]
|
method = 'OnRequest_' + message[ 'command' ]
|
||||||
if method in dir( self._handler ):
|
for h in self._handlers:
|
||||||
getattr( self._handler, method )( message )
|
if method in dir( h ):
|
||||||
else:
|
getattr( h, method )( message )
|
||||||
utils.UserMessage(
|
|
||||||
'Unhandled request: {0}'.format( message[ 'command' ] ),
|
|
||||||
persist = True )
|
|
||||||
|
|
||||||
|
|
||||||
def _KillTimer( request ):
|
def _KillTimer( request ):
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import shlex
|
||||||
import subprocess
|
import subprocess
|
||||||
import functools
|
import functools
|
||||||
import vim
|
import vim
|
||||||
|
import importlib
|
||||||
|
|
||||||
from vimspector import ( breakpoints,
|
from vimspector import ( breakpoints,
|
||||||
code,
|
code,
|
||||||
|
|
@ -99,7 +100,7 @@ class DebugSession( object ):
|
||||||
|
|
||||||
return launch_config_file, configurations
|
return launch_config_file, configurations
|
||||||
|
|
||||||
def Start( self, launch_variables = None ):
|
def Start( self, force_choose=False, launch_variables = None ):
|
||||||
# We mutate launch_variables, so don't mutate the default argument.
|
# We mutate launch_variables, so don't mutate the default argument.
|
||||||
# https://docs.python-guide.org/writing/gotchas/#mutable-default-arguments
|
# https://docs.python-guide.org/writing/gotchas/#mutable-default-arguments
|
||||||
if launch_variables is None:
|
if launch_variables is None:
|
||||||
|
|
@ -134,6 +135,11 @@ class DebugSession( object ):
|
||||||
|
|
||||||
if 'configuration' in launch_variables:
|
if 'configuration' in launch_variables:
|
||||||
configuration_name = launch_variables.pop( 'configuration' )
|
configuration_name = launch_variables.pop( 'configuration' )
|
||||||
|
elif force_choose:
|
||||||
|
# Always display the menu
|
||||||
|
configuration_name = utils.SelectFromList(
|
||||||
|
'Which launch configuration?',
|
||||||
|
sorted( configurations.keys() ) )
|
||||||
elif ( len( configurations ) == 1 and
|
elif ( len( configurations ) == 1 and
|
||||||
next( iter( configurations.values() ) ).get( "autoselect", True ) ):
|
next( iter( configurations.values() ) ).get( "autoselect", True ) ):
|
||||||
configuration_name = next( iter( configurations.keys() ) )
|
configuration_name = next( iter( configurations.keys() ) )
|
||||||
|
|
@ -529,6 +535,21 @@ class DebugSession( object ):
|
||||||
def SetVariableValue( self, new_value = None, buf = None, line_num = None ):
|
def SetVariableValue( self, new_value = None, buf = None, line_num = None ):
|
||||||
self._variablesView.SetVariableValue( new_value, buf, line_num )
|
self._variablesView.SetVariableValue( new_value, buf, line_num )
|
||||||
|
|
||||||
|
@IfConnected()
|
||||||
|
def AddDataBreakpoint( self, opts, buf = None, line_num = None ):
|
||||||
|
def add_bp( breakpoint_info ):
|
||||||
|
if breakpoint_info[ 'dataId' ] is None:
|
||||||
|
utils.UserMessage(
|
||||||
|
"Can't set data breakpoint here: { breakpoint_info[ 'description' ] }"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
# TODO: Ask the user about the possible DataBreakpointAccessType's and add
|
||||||
|
# that in to opts here
|
||||||
|
self._breakpoints.AddDataBreakpoint( breakpoint_info[ 'dataId' ], opts )
|
||||||
|
|
||||||
|
self._variablesView.GetDataBreakpointInfo( add_bp, buf, line_num )
|
||||||
|
|
||||||
@IfConnected()
|
@IfConnected()
|
||||||
def AddWatch( self, expression ):
|
def AddWatch( self, expression ):
|
||||||
self._variablesView.AddWatch( self._stackTraceView.GetCurrentFrame(),
|
self._variablesView.AddWatch( self._stackTraceView.GetCurrentFrame(),
|
||||||
|
|
@ -781,8 +802,21 @@ class DebugSession( object ):
|
||||||
self._splash_screen,
|
self._splash_screen,
|
||||||
"Unable to start adapter" )
|
"Unable to start adapter" )
|
||||||
else:
|
else:
|
||||||
|
if 'custom_handler' in self._adapter:
|
||||||
|
spec = self._adapter[ 'custom_handler' ]
|
||||||
|
if isinstance( spec, dict ):
|
||||||
|
module = spec[ 'module' ]
|
||||||
|
cls = spec[ 'class' ]
|
||||||
|
else:
|
||||||
|
module, cls = spec.rsplit( '.', 1 )
|
||||||
|
|
||||||
|
CustomHandler = getattr( importlib.import_module( module ), cls )
|
||||||
|
handlers = [ CustomHandler( self ), self ]
|
||||||
|
else:
|
||||||
|
handlers = [ self ]
|
||||||
|
|
||||||
self._connection = debug_adapter_connection.DebugAdapterConnection(
|
self._connection = debug_adapter_connection.DebugAdapterConnection(
|
||||||
self,
|
handlers,
|
||||||
lambda msg: utils.Call(
|
lambda msg: utils.Call(
|
||||||
"vimspector#internal#{}#Send".format( self._connection_type ),
|
"vimspector#internal#{}#Send".format( self._connection_type ),
|
||||||
msg ) )
|
msg ) )
|
||||||
|
|
@ -790,39 +824,52 @@ class DebugSession( object ):
|
||||||
self._logger.info( 'Debug Adapter Started' )
|
self._logger.info( 'Debug Adapter Started' )
|
||||||
|
|
||||||
def _StopDebugAdapter( self, interactive = False, callback = None ):
|
def _StopDebugAdapter( self, interactive = False, callback = None ):
|
||||||
self._splash_screen = utils.DisplaySplash(
|
def disconnect( arguments = {} ):
|
||||||
self._api_prefix,
|
self._splash_screen = utils.DisplaySplash(
|
||||||
self._splash_screen,
|
self._api_prefix,
|
||||||
"Shutting down debug adapter..." )
|
self._splash_screen,
|
||||||
|
"Shutting down debug adapter..." )
|
||||||
|
|
||||||
def handler( *args ):
|
def handler( *args ):
|
||||||
self._splash_screen = utils.HideSplash( self._api_prefix,
|
self._splash_screen = utils.HideSplash( self._api_prefix,
|
||||||
self._splash_screen )
|
self._splash_screen )
|
||||||
|
|
||||||
if callback:
|
if callback:
|
||||||
self._logger.debug( "Setting server exit handler before disconnect" )
|
self._logger.debug( "Setting server exit handler before disconnect" )
|
||||||
assert not self._run_on_server_exit
|
assert not self._run_on_server_exit
|
||||||
self._run_on_server_exit = callback
|
self._run_on_server_exit = callback
|
||||||
|
|
||||||
vim.eval( 'vimspector#internal#{}#StopDebugSession()'.format(
|
vim.eval( 'vimspector#internal#{}#StopDebugSession()'.format(
|
||||||
self._connection_type ) )
|
self._connection_type ) )
|
||||||
|
|
||||||
arguments = {}
|
self._connection.DoRequest( handler, {
|
||||||
if ( interactive and
|
'command': 'disconnect',
|
||||||
self._server_capabilities.get( 'supportTerminateDebuggee' ) ):
|
'arguments': {},
|
||||||
if self._stackTraceView.AnyThreadsRunning():
|
}, failure_handler = handler, timeout = 5000 )
|
||||||
choice = utils.AskForInput( "Terminate debuggee [Y/N/default]? ", "" )
|
|
||||||
if choice == "Y" or choice == "y":
|
if not interactive:
|
||||||
|
disconnect()
|
||||||
|
elif not self._server_capabilities.get( 'supportTerminateDebuggee' ):
|
||||||
|
disconnect()
|
||||||
|
elif not self._stackTraceView.AnyThreadsRunning():
|
||||||
|
disconnect()
|
||||||
|
else:
|
||||||
|
def handle_choice( choice ):
|
||||||
|
arguments = {}
|
||||||
|
if choice == 1:
|
||||||
arguments[ 'terminateDebuggee' ] = True
|
arguments[ 'terminateDebuggee' ] = True
|
||||||
elif choice == "N" or choice == 'n':
|
elif choice == 0:
|
||||||
arguments[ 'terminateDebuggee' ] = False
|
arguments[ 'terminateDebuggee' ] = False
|
||||||
|
elif choice == -1:
|
||||||
|
# Abort
|
||||||
|
return
|
||||||
|
|
||||||
self._connection.DoRequest( handler, {
|
disconnect( arguments )
|
||||||
'command': 'disconnect',
|
|
||||||
'arguments': arguments,
|
|
||||||
}, failure_handler = handler, timeout = 5000 )
|
|
||||||
|
|
||||||
# TODO: Use the 'tarminate' request if supportsTerminateRequest set
|
utils.Confirm( self._api_prefix,
|
||||||
|
"Terminate debuggee?",
|
||||||
|
handle_choice,
|
||||||
|
default_value = 3 )
|
||||||
|
|
||||||
|
|
||||||
def _PrepareAttach( self, adapter_config, launch_config ):
|
def _PrepareAttach( self, adapter_config, launch_config ):
|
||||||
|
|
@ -1002,6 +1049,10 @@ class DebugSession( object ):
|
||||||
#
|
#
|
||||||
def handle_initialize_response( msg ):
|
def handle_initialize_response( msg ):
|
||||||
self._server_capabilities = msg.get( 'body' ) or {}
|
self._server_capabilities = msg.get( 'body' ) or {}
|
||||||
|
self._outputView.Print(
|
||||||
|
'server',
|
||||||
|
'Server Capabilities:\n' + json.dumps( self._server_capabilities,
|
||||||
|
indent = 2 ) )
|
||||||
self._breakpoints.SetServerCapabilities( self._server_capabilities )
|
self._breakpoints.SetServerCapabilities( self._server_capabilities )
|
||||||
self._variablesView.SetServerCapabilities( self._server_capabilities )
|
self._variablesView.SetServerCapabilities( self._server_capabilities )
|
||||||
self._Launch()
|
self._Launch()
|
||||||
|
|
|
||||||
|
|
@ -159,7 +159,8 @@ GADGETS = {
|
||||||
"port": "${DAPPort}",
|
"port": "${DAPPort}",
|
||||||
"configuration": {
|
"configuration": {
|
||||||
"cwd": "${workspaceRoot}"
|
"cwd": "${workspaceRoot}"
|
||||||
}
|
},
|
||||||
|
'custom_handler': 'vimspector.custom.java.JavaDebugAdapter'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -64,8 +64,8 @@ class OutputView( object ):
|
||||||
self._api_prefix = api_prefix
|
self._api_prefix = api_prefix
|
||||||
VIEWS.add( self )
|
VIEWS.add( self )
|
||||||
|
|
||||||
def Print( self, categroy, text ):
|
def Print( self, category, text ):
|
||||||
self._Print( 'server', text.splitlines() )
|
self._Print( category, text.splitlines() )
|
||||||
|
|
||||||
def OnOutput( self, event ):
|
def OnOutput( self, event ):
|
||||||
category = CategoryToBuffer( event.get( 'category' ) or 'output' )
|
category = CategoryToBuffer( event.get( 'category' ) or 'output' )
|
||||||
|
|
|
||||||
|
|
@ -375,6 +375,31 @@ def AskForInput( prompt, default_value = None, completion = None ):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
CONFIRM = {}
|
||||||
|
CONFIRM_ID = 0
|
||||||
|
|
||||||
|
def ConfirmCallback( confirm_id, result ):
|
||||||
|
try:
|
||||||
|
handler = CONFIRM.pop( confirm_id )
|
||||||
|
except KeyError:
|
||||||
|
UserMessage( f"Internal error: unexpected callback id { confirm_id }",
|
||||||
|
persist = True,
|
||||||
|
error = True )
|
||||||
|
return
|
||||||
|
|
||||||
|
handler( result )
|
||||||
|
|
||||||
|
|
||||||
|
def Confirm( api_prefix, prompt, handler, default_value = 1 ):
|
||||||
|
global CONFIRM_ID
|
||||||
|
CONFIRM_ID += 1
|
||||||
|
CONFIRM[ CONFIRM_ID ] = handler
|
||||||
|
Call( f'vimspector#internal#{ api_prefix }popup#Confirm',
|
||||||
|
CONFIRM_ID,
|
||||||
|
prompt,
|
||||||
|
default_value )
|
||||||
|
|
||||||
|
|
||||||
def AppendToBuffer( buf, line_or_lines, modified=False ):
|
def AppendToBuffer( buf, line_or_lines, modified=False ):
|
||||||
line = 1
|
line = 1
|
||||||
try:
|
try:
|
||||||
|
|
@ -403,8 +428,10 @@ def AppendToBuffer( buf, line_or_lines, modified=False ):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def ClearBuffer( buf ):
|
def ClearBuffer( buf, modified = False ):
|
||||||
buf[ : ] = None
|
buf[ : ] = None
|
||||||
|
if not modified:
|
||||||
|
buf.options[ 'modified' ] = False
|
||||||
|
|
||||||
|
|
||||||
def SetBufferContents( buf, lines, modified=False ):
|
def SetBufferContents( buf, lines, modified=False ):
|
||||||
|
|
|
||||||
|
|
@ -580,6 +580,33 @@ class VariablesView( object ):
|
||||||
}, failure_handler = failure_handler )
|
}, failure_handler = failure_handler )
|
||||||
|
|
||||||
|
|
||||||
|
def GetDataBreakpointInfo( self,
|
||||||
|
then,
|
||||||
|
buf = None,
|
||||||
|
line_num = None ):
|
||||||
|
variable: Variable
|
||||||
|
view: View
|
||||||
|
|
||||||
|
if not self._server_capabilities.get( 'supportsDataBreakpoints' ):
|
||||||
|
return None
|
||||||
|
|
||||||
|
variable, view = self._GetVariable( buf, line_num )
|
||||||
|
if variable is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
arguments = {
|
||||||
|
'name': variable.variable[ 'name' ],
|
||||||
|
}
|
||||||
|
if variable.IsContained():
|
||||||
|
arguments[ 'variablesReference' ] = (
|
||||||
|
variable.container.VariablesReference() )
|
||||||
|
|
||||||
|
self._connection.DoRequest( lambda msg: then( msg[ 'body' ] ), {
|
||||||
|
'command': 'dataBreakpointInfo',
|
||||||
|
'arguments': arguments,
|
||||||
|
} )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _DrawVariables( self, view, variables, indent, is_short = False ):
|
def _DrawVariables( self, view, variables, indent, is_short = False ):
|
||||||
assert indent > 0
|
assert indent > 0
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,25 @@
|
||||||
package main
|
package main
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
|
type Toaster struct {
|
||||||
|
Power int
|
||||||
|
Colour string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Test struct {
|
||||||
|
Test string
|
||||||
|
Toast Toaster
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var v = "test"
|
var v = "test"
|
||||||
|
test := Test{
|
||||||
|
Test: "This is\na\ntest",
|
||||||
|
Toast: Toaster{
|
||||||
|
Power: 10,
|
||||||
|
Colour: "green",
|
||||||
|
},
|
||||||
|
}
|
||||||
fmt.Println("hello world: " + v)
|
fmt.Println("hello world: " + v)
|
||||||
|
fmt.Println("Hi " + test.Test)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
<artifactId>TestApplication</artifactId>
|
<artifactId>TestApplication</artifactId>
|
||||||
<version>1</version>
|
<version>1</version>
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.source>8</maven.compiler.source>
|
<maven.compiler.source>11</maven.compiler.source>
|
||||||
<maven.compiler.target>8</maven.compiler.target>
|
<maven.compiler.target>11</maven.compiler.target>
|
||||||
</properties>
|
</properties>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue