From c9a45b3bdcb4d1e5daf1b0c90fd53464f7c488c0 Mon Sep 17 00:00:00 2001 From: Ben Jackson Date: Tue, 22 May 2018 23:59:15 +0100 Subject: [PATCH] First attempt to make breakpoints work. Doesn't. Python at least responds with the breakpoints. MS CPP does not, and native debug just throws an error --- autoload/vimspector.vim | 11 +++-- python3/vimspector/code.py | 24 ++++++++++ .../vimspector/debug_adapter_connection.py | 4 +- python3/vimspector/debug_session.py | 44 +++++++++++++++---- python3/vimspector/utils.py | 2 +- 5 files changed, 71 insertions(+), 14 deletions(-) diff --git a/autoload/vimspector.vim b/autoload/vimspector.vim index 6faddd8..96d3c63 100644 --- a/autoload/vimspector.vim +++ b/autoload/vimspector.vim @@ -19,13 +19,18 @@ let s:save_cpo = &cpo set cpo&vim " }}} -" TODO: Test function -function! vimspector#Launch() abort py3 << EOF from vimspector import debug_session _vimspector_session = debug_session.DebugSession() -_vimspector_session.Start() EOF + +" TODO: Test function +function! vimspector#Launch() abort + py3 _vimspector_session.Start() +endfunction + +function! vimspector#ToggleBreakpoint() abort + py3 _vimspector_session.ToggleBreakpoint() endfunction function! vimspector#StepOver() abort diff --git a/python3/vimspector/code.py b/python3/vimspector/code.py index d2f5938..2bd8371 100644 --- a/python3/vimspector/code.py +++ b/python3/vimspector/code.py @@ -14,6 +14,9 @@ # limitations under the License. import vim +import logging +import json +from vimspector import utils SIGN_ID_OFFSET = 10000000 @@ -22,9 +25,13 @@ class CodeView( object ): def __init__( self, window ): self._window = window + self._logger = logging.getLogger( __name__ ) + utils.SetUpLogging( self._logger ) + self._next_sign_id = SIGN_ID_OFFSET self._signs = { 'vimspectorPC': None, + 'breakpoints': [], } @@ -38,6 +45,7 @@ class CodeView( object ): vim.command( 'nnoremenu WinBar.Stop :call vimspector#Stop()' ) vim.command( 'sign define vimspectorPC text=>> texthl=Search' ) + vim.command( 'sign define vimspectorBP text=>> texthl=Error' ) def SetCurrentFrame( self, frame ): @@ -71,3 +79,19 @@ class CodeView( object ): if self._signs[ 'vimspectorPC' ]: vim.command( 'sign unplace {0}'.format( self._signs[ 'vimspectorPC' ] ) ) self._signs[ 'vimspectorPC' ] = None + + + def ShowBreakpoints( self, file_name, breakpoints ): + for sign_id in self._signs[ 'breakpoints' ]: + vim.command( 'sign unplace {0}'.format( sign_id ) ) + + for breakpoint in breakpoints: + sign_id = self._next_sign_id + self._next_sign_id += 1 + self._signs[ 'breakpoints' ].append( sign_id ) + self._logger.debug( 'breakpoint: {0}'.format( json.dumps( breakpoint, + indent=2 ) ) ) + vim.command( 'sign place {0} line={1} name=vimspectorBP file={2}'.format( + sign_id, + breakpoint[ 'line' ], + file_name ) ) diff --git a/python3/vimspector/debug_adapter_connection.py b/python3/vimspector/debug_adapter_connection.py index 1edff4b..a09fc9f 100644 --- a/python3/vimspector/debug_adapter_connection.py +++ b/python3/vimspector/debug_adapter_connection.py @@ -120,8 +120,8 @@ class DebugAdapterConnection( object ): else: self._logger.error( 'Request failed: {0}'.format( message[ 'message' ] ) ) - utils.UserMessage( 'Request failed: {0}'.format( message[ 'message' ], - persist = True ) ) + utils.UserMessage( 'Request failed: {0}'.format( message[ 'message' ] ), + persist = True ) elif message[ 'type' ] == 'event': method = 'OnEvent_' + message[ 'event' ] if method in dir( self._handler ): diff --git a/python3/vimspector/debug_session.py b/python3/vimspector/debug_session.py index 1587c8d..c2a79f5 100644 --- a/python3/vimspector/debug_session.py +++ b/python3/vimspector/debug_session.py @@ -16,6 +16,9 @@ import logging import vim import json +from functools import partial + +from collections import defaultdict from vimspector import ( code, debug_adapter_connection, @@ -38,6 +41,22 @@ class DebugSession( object ): self._currentThread = None self._currentFrame = None + self._breakpoints = defaultdict( dict ) + + def ToggleBreakpoint( self ): + 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 ] + else: + self._breakpoints[ file_name ][ line ] = { + 'state': 'ENABLED', + # 'condition': ..., + # 'hitCondition': ..., + # 'logMessage': ... + } + def Start( self, configuration = None ): launch_config_file = utils.PathToConfigFile( '.vimspector.json' ) @@ -197,15 +216,24 @@ class DebugSession( object ): 'arguments': launch_config } ) + def _UpdateBreakpoints( self, file_name, message ): + self._codeView.ShowBreakpoints( file_name, + message[ 'body' ][ 'breakpoints' ]) + def OnEvent_initialized( self, message ): - self._connection.DoRequest( None, { - 'command': 'setFunctionBreakpoints', - 'arguments': { - 'breakpoints': [ - { 'name': 'main' } # HAAACK: TODO: Support setting breakpoints - ] - }, - } ) + for file_name, line_breakpoints in self._breakpoints.items(): + breakpoints = [ { 'line': line } for line in line_breakpoints.keys() ] + self._connection.DoRequest( + partial( self._UpdateBreakpoints, file_name ), + { + 'command': 'setBreakpoints', + 'arguments': { + 'source': { + 'file': file_name, + }, + 'breakpoints': breakpoints, + }, + } ) self._connection.DoRequest( None, { 'command': 'configurationDone', diff --git a/python3/vimspector/utils.py b/python3/vimspector/utils.py index 5f2ec3b..f119db3 100644 --- a/python3/vimspector/utils.py +++ b/python3/vimspector/utils.py @@ -90,7 +90,7 @@ def UserMessage( msg, persist=False ): vim.command( 'redraw' ) cmd = 'echom' if persist else 'echo' for line in msg.split( '\n' ): - vim.command( '{0} \'{1}\''.format( cmd, Escape( line ) ) ) + vim.command( "{0} '{1}'".format( cmd, Escape( line ) ) ) def SelectFromList( prompt, options ):