Support jumping up/down the stack

Split out stack trace view into its own thing. Support jumping to code
location.
This commit is contained in:
Ben Jackson 2018-05-20 21:38:11 +01:00
commit fa627712e2
3 changed files with 84 additions and 35 deletions

View file

@ -16,7 +16,7 @@
import logging
import vim
from vimspector import utils, variables, debug_adapter_connection
from vimspector import debug_adapter_connection, stack_trace, utils, variables
_logger = logging.getLogger( __name__ )
@ -31,7 +31,6 @@ class DebugSession( object ):
self._uiTab = None
self._codeWindow = None
self._callStackBuffer = None
self._threadsBuffer = None
self._outputBuffer = None
@ -65,8 +64,9 @@ class DebugSession( object ):
# Call stack
vim.command( 'spl' )
vim.command( 'enew' )
self._callStackBuffer = vim.current.buffer
utils.SetUpScratchBuffer( self._callStackBuffer )
self._stackTraceView = stack_trace.StackTraceView( self,
self._connection,
vim.current.buffer )
# Output/logging
vim.command( 'spl' )
@ -81,7 +81,8 @@ class DebugSession( object ):
vim.current.buffer )
def _LoadFrame( self, frame ):
def SetCurrentFrame( self, frame ):
self._currentFrame = frame
vim.current.window = self._codeWindow
buffer_number = vim.eval( 'bufnr( "{0}", 1 )'.format(
frame[ 'source' ][ 'path' ] ) )
@ -95,6 +96,7 @@ class DebugSession( object ):
self._codeWindow.cursor = ( frame[ 'line' ], frame[ 'column' ] )
self._variablesView.LoadScopes( frame )
def OnChannelData( self, data ):
self._connection.OnData( data )
@ -152,6 +154,9 @@ class DebugSession( object ):
def ExpandVariable( self ):
self._variablesView.ExpandVariable()
def GoToFrame( self ):
self._stackTraceView.GoToFrame()
def _Initialise( self ):
def handler( message ) :
self._connection.DoRequest( None, {
@ -218,33 +223,4 @@ class DebugSession( object ):
'command': 'threads',
} )
def stacktrace_printer( message ):
with utils.ModifiableScratchBuffer( self._callStackBuffer ):
self._callStackBuffer.options[ 'modifiable' ] = True
self._callStackBuffer.options[ 'readonly' ] = False
self._callStackBuffer[:] = None
self._callStackBuffer.append( 'Backtrace: ' )
stackFrames = message[ 'body' ][ 'stackFrames' ]
if stackFrames:
self._currentFrame = stackFrames[ 0 ]
else:
self._currentFrame = None
for frame in stackFrames:
self._callStackBuffer.append(
'{0}: {1}@{2}:{3}'.format( frame[ 'id' ],
frame[ 'name' ],
frame[ 'source' ][ 'name' ],
frame[ 'line' ] ) )
self._LoadFrame( self._currentFrame )
self._connection.DoRequest( stacktrace_printer, {
'command': 'stackTrace',
'arguments': {
'threadId': self._currentThread,
}
} )
self._stackTraceView.LoadStackTrace( self._currentThread )

View file

@ -0,0 +1,69 @@
# vimspector - A multi-language debugging system for Vim
# Copyright 2018 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.
import logging
import vim
from vimspector import utils
_logger = logging.getLogger( __name__ )
class StackTraceView( object ):
def __init__( self, session, connection, buf ):
self._buf = buf
self._session = session
self._connection = connection
utils.SetUpScratchBuffer( self._buf )
vim.current.buffer = self._buf
vim.command( 'nnoremap <buffer> <CR> :call vimspector#GoToFrame()<CR>' )
self._line_to_frame = {}
def LoadStackTrace( self, thread_id ):
self._connection.DoRequest( self._PrintStackTrace, {
'command': 'stackTrace',
'arguments': {
'threadId': thread_id,
}
} )
def GoToFrame( self ):
if vim.current.buffer != self._buf:
return
current_line = vim.current.window.cursor[ 0 ]
if current_line not in self._line_to_frame:
return
self._session.SetCurrentFrame( self._line_to_frame[ current_line ] )
def _PrintStackTrace( self, message ):
with utils.ModifiableScratchBuffer( self._buf ):
self._buf[:] = None
self._buf.append( 'Stack trace' )
stackFrames = message[ 'body' ][ 'stackFrames' ]
for frame in stackFrames:
self._buf.append(
'{0}: {1}@{2}:{3}'.format( frame[ 'id' ],
frame[ 'name' ],
frame[ 'source' ][ 'name' ],
frame[ 'line' ] ) )
self._line_to_frame[ len( self._buf ) ] = frame
self._session.SetCurrentFrame( stackFrames[ 0 ] )