Add SetLineBreakpoint and ClaerLineBreakpoint APIs

These are useful for running tests (i.e. ensure there's a breakpiont at
the start of the test) and/or other programmatic usages.

They will also be needed for setting temporary breakpionts.
This commit is contained in:
Ben Jackson 2020-10-13 22:16:11 +01:00
commit 0d112d70a0
5 changed files with 105 additions and 44 deletions

View file

@ -141,50 +141,74 @@ class ProjectBreakpoints( object ):
self.UpdateUI()
def _FindLineBreakpoint( self, file_name, line ):
file_name = os.path.abspath( file_name )
for index, bp in enumerate( self._line_breakpoints[ file_name ] ):
self._SignToLine( file_name, bp )
if bp[ 'line' ] == line:
return bp, index
return None, None
def _PutLineBreakpoint( self, file_name, line, options ):
self._line_breakpoints[ os.path.abspath( file_name ) ].append( {
'state': 'ENABLED',
'line': line,
'options': options,
# 'sign_id': <filled in when placed>,
#
# Used by other breakpoint types (specified in options):
# 'condition': ...,
# 'hitCondition': ...,
# 'logMessage': ...
} )
def _DeleteLineBreakpoint( self, bp, file_name, index ):
if 'sign_id' in bp:
signs.UnplaceSign( bp[ 'sign_id' ], 'VimspectorBP' )
del self._line_breakpoints[ os.path.abspath( file_name ) ][ index ]
def ToggleBreakpoint( self, options ):
line, column = vim.current.window.cursor
line, _ = vim.current.window.cursor
file_name = vim.current.buffer.name
if not file_name:
return
found_bp = False
action = 'New'
for index, bp in enumerate( self._line_breakpoints[ file_name ] ):
self._SignToLine( file_name, bp )
if bp[ 'line' ] == line:
found_bp = True
if bp[ 'state' ] == 'ENABLED' and not self._connection:
bp[ 'state' ] = 'DISABLED'
action = 'Disable'
else:
if 'sign_id' in bp:
signs.UnplaceSign( bp[ 'sign_id' ], 'VimspectorBP' )
del self._line_breakpoints[ file_name ][ index ]
action = 'Delete'
break
self._logger.debug( "Toggle found bp at {}:{} ? {} ({})".format(
file_name,
line,
found_bp,
action ) )
if not found_bp:
self._line_breakpoints[ file_name ].append( {
'state': 'ENABLED',
'line': line,
'options': options,
# 'sign_id': <filled in when placed>,
#
# Used by other breakpoint types (specified in options):
# 'condition': ...,
# 'hitCondition': ...,
# 'logMessage': ...
} )
bp, index = self._FindLineBreakpoint( file_name, line )
if bp is None:
# ADD
self._PutLineBreakpoint( file_name, line, options )
elif bp[ 'state' ] == 'ENABLED' and not self._connection:
# DISABLE
bp[ 'state' ] = 'DISABLED'
else:
# DELETE
self._DeleteLineBreakpoint( bp, file_name, index )
self.UpdateUI()
def SetLineBreakpoint( self, file_name, line_num, options ):
bp, _ = self._FindLineBreakpoint( file_name, line_num )
if bp is not None:
bp[ 'options' ] = options
return
self._PutLineBreakpoint( file_name, line_num, options )
self.UpdateUI()
def ClearLineBreakpoint( self, file_name, line_num ):
bp, index = self._FindLineBreakpoint( file_name, line_num )
if bp is None:
return
self._DeleteLineBreakpoint( bp, file_name, index )
self.UpdateUI()
def AddFunctionBreakpoint( self, function, options ):
self._func_breakpoints.append( {
'state': 'ENABLED',
@ -386,17 +410,21 @@ class ProjectBreakpoints( object ):
else 'vimspectorBPCond' if 'condition' in bp[ 'options' ]
else 'vimspectorBP' )
signs.PlaceSign( bp[ 'sign_id' ],
'VimspectorBP',
sign,
file_name,
bp[ 'line' ] )
if utils.BufferNumberForFile( file_name, False ) > 0:
signs.PlaceSign( bp[ 'sign_id' ],
'VimspectorBP',
sign,
file_name,
bp[ 'line' ] )
def _SignToLine( self, file_name, bp ):
if 'sign_id' not in bp:
return bp[ 'line' ]
if utils.BufferNumberForFile( file_name, False ) <= 0:
return bp[ 'line' ]
signs = vim.eval( "sign_getplaced( '{}', {} )".format(
utils.Escape( file_name ),
json.dumps( { 'id': bp[ 'sign_id' ], 'group': 'VimspectorBP', } ) ) )

View file

@ -1165,6 +1165,12 @@ class DebugSession( object ):
def ToggleBreakpoint( self, options ):
return self._breakpoints.ToggleBreakpoint( options )
def SetLineBreakpoint( self, file_name, line_num, options ):
return self._breakpoints.SetLineBreakpoint( file_name, line_num, options )
def ClearLineBreakpoint( self, file_name, line_num ):
return self._breakpoints.ClearLineBreakpoint( file_name, line_num )
def ClearBreakpoints( self ):
if self._connection:
self._codeView.ClearBreakpoints()

View file

@ -29,7 +29,7 @@ def DefineSign( name, text, double_text, texthl, col = 'right', **kwargs ):
vim.command( cmd )
def PlaceSign( sign_id, group, name, file, line ):
def PlaceSign( sign_id, group, name, file_name, line ):
priority = settings.Dict( 'sign_priority' )[ name ]
cmd = ( f'sign place { sign_id } '
@ -37,7 +37,7 @@ def PlaceSign( sign_id, group, name, file, line ):
f'name={ name } '
f'priority={ priority } '
f'line={ line } '
f'file={ file }' )
f'file={ file_name }' )
vim.command( cmd )

View file

@ -45,8 +45,10 @@ _logger = logging.getLogger( __name__ )
SetUpLogging( _logger )
def BufferNumberForFile( file_name ):
return int( vim.eval( "bufnr( '{0}', 1 )".format( Escape( file_name ) ) ) )
def BufferNumberForFile( file_name, create = True ):
return int( vim.eval( "bufnr( '{0}', {1} )".format(
Escape( file_name ),
int( create ) ) ) )
def BufferForFile( file_name ):