Fix crash; enable syntax highlighting in hover popup; use a Watch for the popup and re-use existing drawing code
This commit is contained in:
parent
0895c5e829
commit
64e38b57ab
1 changed files with 61 additions and 56 deletions
|
|
@ -117,14 +117,27 @@ class Watch:
|
||||||
self.expression = expression
|
self.expression = expression
|
||||||
self.result = None
|
self.result = None
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def New( frame, expression, context ):
|
||||||
|
watch = {
|
||||||
|
'expression': expression,
|
||||||
|
'context': context,
|
||||||
|
}
|
||||||
|
if frame:
|
||||||
|
watch[ 'frameId' ] = frame[ 'id' ]
|
||||||
|
|
||||||
|
return Watch( watch )
|
||||||
|
|
||||||
|
|
||||||
class View:
|
class View:
|
||||||
lines: typing.Dict[ int, Expandable ]
|
lines: typing.Dict[ int, Expandable ]
|
||||||
draw: typing.Callable
|
draw: typing.Callable
|
||||||
|
syntax: str
|
||||||
|
|
||||||
def __init__( self, win, lines, draw ):
|
def __init__( self, win, lines, draw ):
|
||||||
self.lines = lines
|
self.lines = lines
|
||||||
self.draw = draw
|
self.draw = draw
|
||||||
|
self.syntax = None
|
||||||
if ( win is not None ):
|
if ( win is not None ):
|
||||||
self.buf = win.buffer
|
self.buf = win.buffer
|
||||||
utils.SetUpUIWindow( win )
|
utils.SetUpUIWindow( win )
|
||||||
|
|
@ -186,8 +199,8 @@ class VariablesView( object ):
|
||||||
'balloonexpr': vim.options[ 'balloonexpr' ],
|
'balloonexpr': vim.options[ 'balloonexpr' ],
|
||||||
'balloondelay': vim.options[ 'balloondelay' ],
|
'balloondelay': vim.options[ 'balloondelay' ],
|
||||||
}
|
}
|
||||||
vim.options[ 'balloonexpr' ] = "vimspector#internal#"
|
vim.options[ 'balloonexpr' ] = ( "vimspector#internal#"
|
||||||
"balloon#HoverTooltip()"
|
"balloon#HoverTooltip()" )
|
||||||
|
|
||||||
vim.options[ 'balloondelay' ] = 250
|
vim.options[ 'balloondelay' ] = 250
|
||||||
|
|
||||||
|
|
@ -273,28 +286,25 @@ class VariablesView( object ):
|
||||||
} )
|
} )
|
||||||
|
|
||||||
def _DrawEval( self ):
|
def _DrawEval( self ):
|
||||||
|
watch = self._variable_eval
|
||||||
|
view = self._variable_eval_view
|
||||||
|
|
||||||
with utils.RestoreCursorPosition():
|
with utils.RestoreCursorPosition():
|
||||||
with utils.ModifiableScratchBuffer( self._variable_eval_view.buf ):
|
with utils.ModifiableScratchBuffer( view.buf ):
|
||||||
utils.ClearBuffer( self._variable_eval_view.buf )
|
utils.ClearBuffer( view.buf )
|
||||||
# if we only have a single non-expandable variable,
|
# FIXME: This probably doesn't work reliably
|
||||||
# it means we ran into a simple type
|
view.syntax = utils.SetSyntax( view.syntax,
|
||||||
# hence, there is no need to draw additional fluff around the value
|
self._current_syntax,
|
||||||
if(
|
view.buf )
|
||||||
len( self._variable_eval.variables ) == 1
|
|
||||||
and self._variable_eval.variables[ 0 ].IsExpandable() is False
|
utils.AppendToBuffer(
|
||||||
):
|
view.buf,
|
||||||
utils.AppendToBuffer(
|
f"Expression: { watch.expression[ 'expression' ] }" )
|
||||||
self._variable_eval_view.buf,
|
|
||||||
self._variable_eval.variables[ 0 ]
|
self._DrawWatchResult( view,
|
||||||
.variable.get( 'value', '<unknown>' )
|
2,
|
||||||
)
|
watch,
|
||||||
else:
|
is_short = True )
|
||||||
self._DrawVariables(
|
|
||||||
self._variable_eval_view,
|
|
||||||
self._variable_eval.variables,
|
|
||||||
2,
|
|
||||||
True
|
|
||||||
)
|
|
||||||
|
|
||||||
vim.eval( "vimspector#internal#balloon#nvim_resize_tooltip()" )
|
vim.eval( "vimspector#internal#balloon#nvim_resize_tooltip()" )
|
||||||
|
|
||||||
|
|
@ -309,9 +319,13 @@ class VariablesView( object ):
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def handler( message ):
|
def handler( message ):
|
||||||
body = message[ 'body' ]
|
|
||||||
|
|
||||||
self._variable_eval = Scope( body )
|
watch = self._variable_eval
|
||||||
|
if watch.result is None:
|
||||||
|
watch.result = WatchResult( message[ 'body' ] )
|
||||||
|
else:
|
||||||
|
watch.result.Update( message[ 'body' ] )
|
||||||
|
|
||||||
float_win_id = utils.DisplayBaloon( self._is_term, [], is_hover )
|
float_win_id = utils.DisplayBaloon( self._is_term, [], is_hover )
|
||||||
float_buf_nr = int( vim.eval( "winbufnr({})".format( float_win_id ) ) )
|
float_buf_nr = int( vim.eval( "winbufnr({})".format( float_win_id ) ) )
|
||||||
|
|
||||||
|
|
@ -328,51 +342,41 @@ class VariablesView( object ):
|
||||||
self._DrawEval
|
self._DrawEval
|
||||||
)
|
)
|
||||||
|
|
||||||
if( self._variable_eval.VariablesReference() > 0 ):
|
if watch.result.IsExpandable():
|
||||||
|
# Always expand the first level
|
||||||
|
watch.result.expanded = Expandable.EXPANDED_BY_US
|
||||||
|
|
||||||
|
if watch.result.IsExpanded():
|
||||||
self._connection.DoRequest( partial( self._ConsumeVariables,
|
self._connection.DoRequest( partial( self._ConsumeVariables,
|
||||||
self._DrawEval,
|
self._variable_eval_view.draw,
|
||||||
self._variable_eval ), {
|
watch.result ), {
|
||||||
'command': 'variables',
|
'command': 'variables',
|
||||||
'arguments': {
|
'arguments': {
|
||||||
'variablesReference': self._variable_eval.VariablesReference(),
|
'variablesReference': watch.result.VariablesReference(),
|
||||||
},
|
},
|
||||||
} )
|
} )
|
||||||
else:
|
|
||||||
# in case that there is nothing to expand,
|
|
||||||
# we need to simulate a response from 'variables' request
|
|
||||||
# it returns [Variable]
|
|
||||||
self._variable_eval.variables = [
|
|
||||||
Variable( { 'type': body[ 'type' ], 'value': body[ 'result' ] } )
|
|
||||||
]
|
|
||||||
self._DrawEval()
|
|
||||||
|
|
||||||
|
self._DrawEval()
|
||||||
|
|
||||||
def failure_handler( reason, message ):
|
def failure_handler( reason, message ):
|
||||||
display = [ reason ]
|
display = [ reason ]
|
||||||
utils.DisplayBaloon( self._is_term, display, is_hover )
|
utils.DisplayBaloon( self._is_term, display, is_hover )
|
||||||
|
|
||||||
|
self._variable_eval = Watch.New( frame,
|
||||||
|
expression,
|
||||||
|
'hover' )
|
||||||
|
|
||||||
# Send async request
|
# Send async request
|
||||||
self._connection.DoRequest( handler, {
|
self._connection.DoRequest( handler, {
|
||||||
'command': 'evaluate',
|
'command': 'evaluate',
|
||||||
'arguments': {
|
'arguments': self._variable_eval.expression,
|
||||||
'expression': expression,
|
|
||||||
'frameId': frame[ 'id' ],
|
|
||||||
'context': 'hover',
|
|
||||||
}
|
|
||||||
}, failure_handler )
|
}, failure_handler )
|
||||||
|
|
||||||
# Return working (meanwhile)
|
# Return working (meanwhile)
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def AddWatch( self, frame, expression ):
|
def AddWatch( self, frame, expression ):
|
||||||
watch = {
|
self._watches.append( Watch.New( frame, expression, 'watch' ) )
|
||||||
'expression': expression,
|
|
||||||
'context': 'watch',
|
|
||||||
}
|
|
||||||
if frame:
|
|
||||||
watch[ 'frameId' ] = frame[ 'id' ]
|
|
||||||
|
|
||||||
self._watches.append( Watch( watch ) )
|
|
||||||
self.EvaluateWatches()
|
self.EvaluateWatches()
|
||||||
|
|
||||||
def DeleteWatch( self ):
|
def DeleteWatch( self ):
|
||||||
|
|
@ -470,7 +474,7 @@ class VariablesView( object ):
|
||||||
},
|
},
|
||||||
} )
|
} )
|
||||||
|
|
||||||
def _DrawVariables( self, view, variables, indent, is_short = False ):
|
def _DrawVariables( self, view, variables, indent, is_short = False ):
|
||||||
assert indent > 0
|
assert indent > 0
|
||||||
for variable in variables:
|
for variable in variables:
|
||||||
text = ''
|
text = ''
|
||||||
|
|
@ -530,7 +534,7 @@ class VariablesView( object ):
|
||||||
'Expression: '
|
'Expression: '
|
||||||
+ watch.expression[ 'expression' ] )
|
+ watch.expression[ 'expression' ] )
|
||||||
watch.line = line
|
watch.line = line
|
||||||
self._DrawWatchResult( 2, watch )
|
self._DrawWatchResult( self._watch, 2, watch )
|
||||||
|
|
||||||
def _DrawScope( self, indent, scope ):
|
def _DrawScope( self, indent, scope ):
|
||||||
icon = '+' if scope.IsExpandable() and not scope.IsExpanded() else '-'
|
icon = '+' if scope.IsExpandable() and not scope.IsExpanded() else '-'
|
||||||
|
|
@ -546,7 +550,7 @@ class VariablesView( object ):
|
||||||
indent += 2
|
indent += 2
|
||||||
self._DrawVariables( self._vars, scope.variables, indent )
|
self._DrawVariables( self._vars, scope.variables, indent )
|
||||||
|
|
||||||
def _DrawWatchResult( self, indent, watch ):
|
def _DrawWatchResult( self, view, indent, watch, is_short = False ):
|
||||||
if not watch.result:
|
if not watch.result:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -561,12 +565,12 @@ class VariablesView( object ):
|
||||||
icon = icon,
|
icon = icon,
|
||||||
result = watch.result.result.get( 'result', '<unknown>' ) )
|
result = watch.result.result.get( 'result', '<unknown>' ) )
|
||||||
|
|
||||||
line = utils.AppendToBuffer( self._watch.buf, line.split( '\n' ) )
|
line = utils.AppendToBuffer( view.buf, line.split( '\n' ) )
|
||||||
self._watch.lines[ line ] = watch.result
|
view.lines[ line ] = watch.result
|
||||||
|
|
||||||
if watch.result.ShouldDrawDrillDown():
|
if watch.result.ShouldDrawDrillDown():
|
||||||
indent = 4
|
indent = 4
|
||||||
self._DrawVariables( self._watch, watch.result.variables, indent )
|
self._DrawVariables( view, watch.result.variables, indent, is_short )
|
||||||
|
|
||||||
def _ConsumeVariables( self, draw, parent, message ):
|
def _ConsumeVariables( self, draw, parent, message ):
|
||||||
new_variables = []
|
new_variables = []
|
||||||
|
|
@ -640,6 +644,7 @@ class VariablesView( object ):
|
||||||
|
|
||||||
|
|
||||||
def SetSyntax( self, syntax ):
|
def SetSyntax( self, syntax ):
|
||||||
|
# TODO: Switch to View.syntax
|
||||||
self._current_syntax = utils.SetSyntax( self._current_syntax,
|
self._current_syntax = utils.SetSyntax( self._current_syntax,
|
||||||
syntax,
|
syntax,
|
||||||
self._vars.buf,
|
self._vars.buf,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue