Separate out the display of 'requested' and 'applied' breakpoints

This is a mess, with a load of duplication, but it's a step. When you
request a breakpoint, we add one (in state ENABLED). You can then toggle
it again to change to DISABLED. And once more to delete it.

Once we start the debug server, that all changes and we just start
sending the breakpoints directly to the server and updating based on the
responses. This is far from ideal and somewhat jarring, but this
approach allows me to play around with ideas about what the user
experience should look like.
This commit is contained in:
Ben Jackson 2018-05-26 19:54:45 +01:00
commit 7d3af848cf
2 changed files with 66 additions and 10 deletions

View file

@ -37,7 +37,6 @@ class CodeView( object ):
'breakpoints': []
}
vim.current.window = self._window
vim.command( 'nnoremenu WinBar.Continute :call vimspector#Continue()<CR>' )
@ -47,9 +46,7 @@ class CodeView( object ):
vim.command( 'nnoremenu WinBar.Pause :call vimspector#Pause()<CR>' )
vim.command( 'nnoremenu WinBar.Stop :call vimspector#Stop()<CR>' )
vim.command( 'sign define vimspectorPC text=>> texthl=Search' )
vim.command( 'sign define vimspectorBP text=>> texthl=Error' )
vim.command( 'sign define vimspectorBPDead text=>> texthl=Warning' )
vim.command( 'sign define vimspectorPC text=> texthl=Search' )
def SetCurrentFrame( self, frame ):
@ -85,6 +82,8 @@ class CodeView( object ):
self._signs[ 'vimspectorPC' ] = None
# TODO: You know what, move breakpoint handling out of here into its own
# thing. It really doesn't directly relate to the code view.
def AddBreakpoints( self, source, breakpoints ):
for breakpoint in breakpoints:
if 'source' not in breakpoint:
@ -124,5 +123,6 @@ class CodeView( object ):
'sign place {0} line={1} name={2} file={3}'.format(
sign_id,
breakpoint[ 'line' ],
'vimspectorBP' if breakpoint[ 'verified' ] else 'vimspectorBPDead',
'vimspectorBP' if breakpoint[ 'verified' ]
else 'vimspectorBPDisabled',
file_name ) )

View file

@ -27,6 +27,8 @@ from vimspector import ( code,
utils,
variables )
SIGN_ID_OFFSET = 10005000
class DebugSession( object ):
def __init__( self ):
@ -41,16 +43,30 @@ class DebugSession( object ):
self._currentThread = None
self._currentFrame = None
self._next_sign_id = SIGN_ID_OFFSET
# TODO: Move to code view and consolidate into user-requested-breakpoints,
# and actual breakpoints ?
self._breakpoints = defaultdict( dict )
self._configuration = None
vim.command( 'sign define vimspectorBP text=o texthl=Error' )
vim.command( 'sign define vimspectorBPDisabled text=! texthl=Warning' )
def ToggleBreakpoint( self ):
# TODO: Move this to the code view. Problem is that CodeView doesn't exist
# until we have initialised.
line, column = vim.current.window.cursor
file_name = vim.current.buffer.name
if line in self._breakpoints[ file_name ]:
del self._breakpoints[ file_name ][ line ]
bp = self._breakpoints[ file_name ][ line ]
if bp[ 'state' ] == 'ENABLED':
bp[ 'state' ] = 'DISABLED'
else:
if 'sign_id' in bp:
vim.command( 'sign unplace {0}'.format( bp[ 'sign_id' ] ) )
del self._breakpoints[ file_name ][ line ]
else:
self._breakpoints[ file_name ][ line ] = {
'state': 'ENABLED',
@ -59,6 +75,12 @@ class DebugSession( object ):
# 'logMessage': ...
}
if self._connection:
self._SendBreakpoints()
else:
self._ShowBreakpoints()
def Start( self, configuration = None ):
launch_config_file = utils.PathToConfigFile( '.vimspector.json' )
@ -221,25 +243,42 @@ class DebugSession( object ):
def OnEvent_initialized( self, message ):
self._codeView.ClearBreakpoints()
self._SendBreakpoints()
def _SendBreakpoints( self ):
for file_name, line_breakpoints in self._breakpoints.items():
breakpoints = [ { 'line': line } for line in line_breakpoints.keys() ]
breakpoints = []
lines = []
for line, bp in line_breakpoints.items():
if bp[ 'state' ] != 'ENABLED':
continue
if 'sign_id' in bp:
vim.command( 'sign unplace {0}'.format( bp[ 'sign_id' ] ) )
del bp[ 'sign_id' ]
breakpoints.append( { 'line': line } )
lines.append( line )
source = {
'name': os.path.basename( file_name ),
'path': file_name,
}
self._connection.DoRequest(
functools.partial( self._UpdateBreakpoints, source ),
{
'command': 'setBreakpoints',
'arguments': {
'source': source,
'breakpoints': breakpoints,
'lines': [ line for line in line_breakpoints.keys() ],
'sourceModified': False,
'breakpoints': breakpoints
},
'lines': lines,
'sourceModified': False, # TODO: We can actually check this
}
)
# TODO: Remove this!
self._connection.DoRequest(
functools.partial( self._UpdateBreakpoints, None ),
{
@ -256,6 +295,23 @@ class DebugSession( object ):
'command': 'configurationDone',
} )
def _ShowBreakpoints( self ):
for file_name, line_breakpoints in self._breakpoints.items():
for line, bp in line_breakpoints.items():
if 'sign_id' in bp:
vim.command( 'sign unplace {0}'.format( bp[ 'sign_id' ] ) )
else:
bp[ 'sign_id' ] = self._next_sign_id
self._next_sign_id += 1
vim.command(
'sign place {0} line={1} name={2} file={3}'.format(
bp[ 'sign_id' ] ,
line,
'vimspectorBP' if bp[ 'state' ] == 'ENABLED'
else 'vimspectorBPDisabled',
file_name ) )
def OnEvent_output( self, message ):
with utils.ModifiableScratchBuffer( self._outputBuffer ):
t = [ message[ 'body' ][ 'category' ] + ':' + '-' * 20 ]