Very basic balloon support.
This is a huge hack, setting it manually and never resetting it. Just displaying the value (no breakdown) etc. I'm tempted to drop this functionality altogether as it is of limited use when you have the locals and watch windows.
This commit is contained in:
parent
7e76c9763d
commit
6aecfb969b
4 changed files with 76 additions and 27 deletions
34
autoload/vimspector/internal/balloon.vim
Normal file
34
autoload/vimspector/internal/balloon.vim
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
" 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.
|
||||||
|
|
||||||
|
|
||||||
|
" Boilerplate {{{
|
||||||
|
let s:save_cpo = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
" }}}
|
||||||
|
|
||||||
|
function vimspector#internal#balloon#BalloonExpr()
|
||||||
|
" winnr + 1 because for *no good reason* winnr is 0 based here unlike
|
||||||
|
" everywhere else
|
||||||
|
" int() because for *no good reason* winnr is a string.
|
||||||
|
py3 _vimspector_session.ShowBalloon( int( vim.eval( 'v:beval_winnr' ) ) + 1,
|
||||||
|
\ vim.eval( 'v:beval_text' ) )
|
||||||
|
return ''
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Boilerplate {{{
|
||||||
|
let &cpo=s:save_cpo
|
||||||
|
unlet s:save_cpo
|
||||||
|
" }}}
|
||||||
|
|
@ -186,6 +186,14 @@ class DebugSession( object ):
|
||||||
def DeleteWatch( self ):
|
def DeleteWatch( self ):
|
||||||
self._variablesView.DeleteWatch()
|
self._variablesView.DeleteWatch()
|
||||||
|
|
||||||
|
def ShowBalloon( self, winnr, expression ):
|
||||||
|
if winnr == int( self._codeView._window.number ):
|
||||||
|
self._variablesView.ShowBalloon( self._currentFrame, expression )
|
||||||
|
else:
|
||||||
|
self._logger.debug( 'Winnr {0} is not the code window {1}'.format(
|
||||||
|
winnr,
|
||||||
|
self._codeView._window.number ) )
|
||||||
|
|
||||||
def GoToFrame( self ):
|
def GoToFrame( self ):
|
||||||
self._stackTraceView.GoToFrame()
|
self._stackTraceView.GoToFrame()
|
||||||
|
|
||||||
|
|
@ -244,11 +252,11 @@ class DebugSession( object ):
|
||||||
self._logger.info( 'Debug Adapter Started' )
|
self._logger.info( 'Debug Adapter Started' )
|
||||||
|
|
||||||
def _StopDebugAdapter( self, callback = None ):
|
def _StopDebugAdapter( self, callback = None ):
|
||||||
self._codeView.Clear()
|
|
||||||
|
|
||||||
def handler( message ):
|
def handler( message ):
|
||||||
vim.eval( 'vimspector#internal#job#StopDebugSession()' )
|
vim.eval( 'vimspector#internal#job#StopDebugSession()' )
|
||||||
self._connection = None
|
self._connection = None
|
||||||
|
self._stackTraceView.ConnectionClosed()
|
||||||
|
self._variablesView.ConnectionClosed()
|
||||||
if callback:
|
if callback:
|
||||||
callback()
|
callback()
|
||||||
|
|
||||||
|
|
@ -261,7 +269,6 @@ class DebugSession( object ):
|
||||||
|
|
||||||
|
|
||||||
def _Initialise( self ):
|
def _Initialise( self ):
|
||||||
# TODO: name is mandatory. forcefully add it
|
|
||||||
self._connection.DoRequest( None, {
|
self._connection.DoRequest( None, {
|
||||||
'command': 'initialize',
|
'command': 'initialize',
|
||||||
'arguments': {
|
'arguments': {
|
||||||
|
|
@ -271,6 +278,8 @@ class DebugSession( object ):
|
||||||
'pathFormat': 'path',
|
'pathFormat': 'path',
|
||||||
},
|
},
|
||||||
} )
|
} )
|
||||||
|
# FIXME: name is mandatory. Forcefully add it (we should really use the
|
||||||
|
# _actual_ name, but that isn't actually remembered at this point)
|
||||||
if 'name' not in self._configuration[ 'configuration' ]:
|
if 'name' not in self._configuration[ 'configuration' ]:
|
||||||
self._configuration[ 'configuration' ][ 'name' ] = 'test'
|
self._configuration[ 'configuration' ][ 'name' ] = 'test'
|
||||||
|
|
||||||
|
|
@ -294,27 +303,17 @@ class DebugSession( object ):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def OnEvent_breakpoint( self, message ):
|
def OnEvent_breakpoint( self, message ):
|
||||||
# Useful:
|
|
||||||
#
|
|
||||||
# /** The reason for the event.
|
|
||||||
# Values: 'changed', 'new', 'removed', etc.
|
|
||||||
# */
|
|
||||||
|
|
||||||
reason = message[ 'body' ][ 'reason' ]
|
reason = message[ 'body' ][ 'reason' ]
|
||||||
bp = message[ 'body' ][ 'breakpoint' ]
|
bp = message[ 'body' ][ 'breakpoint' ]
|
||||||
if reason == 'changed':
|
if reason == 'changed':
|
||||||
self._codeView.UpdateBreakpoint( bp )
|
self._codeView.UpdateBreakpoint( bp )
|
||||||
elif reason == 'new':
|
elif reason == 'new':
|
||||||
self._codeView.AddBreakpoints( None, bp )
|
self._codeView.AddBreakpoints( None, bp )
|
||||||
elif reason == 'removed':
|
|
||||||
# TODO
|
|
||||||
pass
|
|
||||||
else:
|
else:
|
||||||
utils.UserMessage(
|
utils.UserMessage(
|
||||||
'Unrecognised breakpoint event (undocumented): {0}'.format( reason ),
|
'Unrecognised breakpoint event (undocumented): {0}'.format( reason ),
|
||||||
persist = True )
|
persist = True )
|
||||||
|
|
||||||
|
|
||||||
def OnEvent_terminated( self, message ):
|
def OnEvent_terminated( self, message ):
|
||||||
utils.UserMessage( "The program was terminated because: {0}".format(
|
utils.UserMessage( "The program was terminated because: {0}".format(
|
||||||
message.get( 'body', {} ).get( 'reason', "No specific reason" ) ) )
|
message.get( 'body', {} ).get( 'reason', "No specific reason" ) ) )
|
||||||
|
|
@ -326,7 +325,6 @@ class DebugSession( object ):
|
||||||
with utils.ModifiableScratchBuffer( self._threadsBuffer ):
|
with utils.ModifiableScratchBuffer( self._threadsBuffer ):
|
||||||
self._threadsBuffer[:] = None
|
self._threadsBuffer[:] = None
|
||||||
|
|
||||||
|
|
||||||
def _SendBreakpoints( self ):
|
def _SendBreakpoints( self ):
|
||||||
for file_name, line_breakpoints in self._breakpoints.items():
|
for file_name, line_breakpoints in self._breakpoints.items():
|
||||||
breakpoints = []
|
breakpoints = []
|
||||||
|
|
@ -360,19 +358,6 @@ class DebugSession( object ):
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
# TODO: Remove this!
|
|
||||||
# self._connection.DoRequest(
|
|
||||||
# functools.partial( self._UpdateBreakpoints, None ),
|
|
||||||
# {
|
|
||||||
# 'command': 'setFunctionBreakpoints',
|
|
||||||
# 'arguments': {
|
|
||||||
# 'breakpoints': [
|
|
||||||
# { 'name': 'main' },
|
|
||||||
# ],
|
|
||||||
# },
|
|
||||||
# }
|
|
||||||
# )
|
|
||||||
|
|
||||||
self._connection.DoRequest( None, {
|
self._connection.DoRequest( None, {
|
||||||
'command': 'configurationDone',
|
'command': 'configurationDone',
|
||||||
} )
|
} )
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,10 @@ class StackTraceView( object ):
|
||||||
with utils.ModifiableScratchBuffer( self._buf ):
|
with utils.ModifiableScratchBuffer( self._buf ):
|
||||||
self._buf[:] = None
|
self._buf[:] = None
|
||||||
|
|
||||||
|
def ConnectionClosed( self ):
|
||||||
|
self.Clear()
|
||||||
|
self._connection = None
|
||||||
|
|
||||||
def LoadStackTrace( self, thread_id ):
|
def LoadStackTrace( self, thread_id ):
|
||||||
self._connection.DoRequest( self._PrintStackTrace, {
|
self._connection.DoRequest( self._PrintStackTrace, {
|
||||||
'command': 'stackTrace',
|
'command': 'stackTrace',
|
||||||
|
|
|
||||||
|
|
@ -51,10 +51,19 @@ class VariablesView( object ):
|
||||||
|
|
||||||
utils.SetUpScratchBuffer( self._buf, 'vimspector.Variables' )
|
utils.SetUpScratchBuffer( self._buf, 'vimspector.Variables' )
|
||||||
|
|
||||||
|
vim.options[ 'balloonexpr' ] = 'vimspector#internal#balloon#BalloonExpr()'
|
||||||
|
vim.options[ 'ballooneval' ] = True
|
||||||
|
vim.options[ 'balloonevalterm' ] = True
|
||||||
|
vim.options[ 'balloondelay' ] = 250
|
||||||
|
|
||||||
def Clear( self ):
|
def Clear( self ):
|
||||||
with utils.ModifiableScratchBuffer( self._buf ):
|
with utils.ModifiableScratchBuffer( self._buf ):
|
||||||
self._buf[:] = None
|
self._buf[:] = None
|
||||||
|
|
||||||
|
def ConnectionClosed( self ):
|
||||||
|
self.Clear()
|
||||||
|
self._connection = None
|
||||||
|
|
||||||
def LoadScopes( self, frame ):
|
def LoadScopes( self, frame ):
|
||||||
def scopes_consumer( message ):
|
def scopes_consumer( message ):
|
||||||
self._scopes = []
|
self._scopes = []
|
||||||
|
|
@ -198,3 +207,20 @@ class VariablesView( object ):
|
||||||
parent[ '_variables' ].append( variable )
|
parent[ '_variables' ].append( variable )
|
||||||
|
|
||||||
self._DrawScopesAndWatches()
|
self._DrawScopesAndWatches()
|
||||||
|
|
||||||
|
def ShowBalloon( self, frame, expression ):
|
||||||
|
if not self._connection:
|
||||||
|
return
|
||||||
|
|
||||||
|
def handler( message ):
|
||||||
|
vim.eval( "balloon_show( '{0}' )".format(
|
||||||
|
message[ 'body' ][ 'result' ] ) )
|
||||||
|
|
||||||
|
self._connection.DoRequest( handler, {
|
||||||
|
'command': 'evaluate',
|
||||||
|
'arguments': {
|
||||||
|
'expression': expression,
|
||||||
|
'frameId': frame[ 'id' ],
|
||||||
|
'context': 'hover',
|
||||||
|
}
|
||||||
|
} )
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue