WIP: First sort-of untested attempt at readmemory request
This commit is contained in:
parent
1cbb400d42
commit
ba9cb2f6d3
5 changed files with 88 additions and 4 deletions
|
|
@ -223,6 +223,13 @@ function! vimspector#SetVariableValue( ... ) abort
|
|||
endif
|
||||
endfunction
|
||||
|
||||
function! vimspector#ReadMemory() abort
|
||||
if !s:Enabled()
|
||||
return
|
||||
endif
|
||||
py3 _vimspector_session.ReadMemory()
|
||||
endfunction
|
||||
|
||||
function! vimspector#DeleteWatch() abort
|
||||
if !s:Enabled()
|
||||
return
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
import vim
|
||||
import logging
|
||||
import json
|
||||
import os
|
||||
from collections import defaultdict
|
||||
|
||||
from vimspector import utils, terminal, signs
|
||||
|
|
@ -40,6 +41,7 @@ class CodeView( object ):
|
|||
'breakpoints': []
|
||||
}
|
||||
self._current_frame = None
|
||||
self._scratch_buffers = []
|
||||
|
||||
with utils.LetCurrentWindow( self._window ):
|
||||
if utils.UseWinBar():
|
||||
|
|
@ -173,6 +175,10 @@ class CodeView( object ):
|
|||
self.ClearBreakpoints()
|
||||
self.Clear()
|
||||
|
||||
for b in self._scratch_buffers:
|
||||
utils.CleanUpHiddenBuffer( b )
|
||||
self._scratch_buffers = []
|
||||
|
||||
def AddBreakpoints( self, source, breakpoints ):
|
||||
for breakpoint in breakpoints:
|
||||
source = breakpoint.get( 'source' ) or source
|
||||
|
|
@ -287,3 +293,14 @@ class CodeView( object ):
|
|||
# FIXME: Change this tor return the PID rather than having debug_session
|
||||
# work that out
|
||||
return self._terminal.buffer_number
|
||||
|
||||
|
||||
def ShowMemory( self, memoryReference, msg ):
|
||||
buf_name = os.path.join( '_vimspector_mem', memoryReference )
|
||||
buf = utils.BufferForFile( buf_name )
|
||||
self._scratch_buffers.append( buf )
|
||||
utils.SetUpHiddenBuffer( buf, buf_name )
|
||||
with utils.ModifiableScratchBuffer( buf ):
|
||||
utils.SetBufferContents(
|
||||
buf,
|
||||
msg.get( 'body', {} ).get( 'data', 'Cannot read memory' ) )
|
||||
|
|
|
|||
|
|
@ -535,6 +535,32 @@ class DebugSession( object ):
|
|||
def SetVariableValue( self, new_value = None, buf = None, line_num = None ):
|
||||
self._variablesView.SetVariableValue( new_value, buf, line_num )
|
||||
|
||||
@IfConnected()
|
||||
def ReadMemory( self, buf = None, line_num = None ):
|
||||
if not self._server_capabilities.get( 'supportsReadMemoryRequest' ):
|
||||
utils.UserMessage( "Server does not support memory request",
|
||||
error = True )
|
||||
return
|
||||
|
||||
memoryReference = self._variablesView.GetMemoryReference( buf, line_num )
|
||||
|
||||
if memoryReference is None:
|
||||
utils.UserMessage( "Cannot find memory reference for that",
|
||||
error = True )
|
||||
return
|
||||
|
||||
def handler( msg ):
|
||||
self._codeView.ShowMemory( msg )
|
||||
|
||||
self._connection.DoRequest( handler, {
|
||||
'command': 'readMemory',
|
||||
'arguments': {
|
||||
'memoryReference': memoryReference,
|
||||
'count': 10 # TODO: What
|
||||
}
|
||||
} )
|
||||
|
||||
|
||||
@IfConnected()
|
||||
def AddWatch( self, expression ):
|
||||
self._variablesView.AddWatch( self._stackTraceView.GetCurrentFrame(),
|
||||
|
|
@ -1163,7 +1189,8 @@ class DebugSession( object ):
|
|||
'pathFormat': 'path',
|
||||
'supportsVariableType': True,
|
||||
'supportsVariablePaging': False,
|
||||
'supportsRunInTerminalRequest': True
|
||||
'supportsRunInTerminalRequest': True,
|
||||
'supportsMemoryReferences': True
|
||||
},
|
||||
} )
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,8 @@ DEFAULTS = {
|
|||
'variables': {
|
||||
'expand_collapse': [ '<CR>', '<2-LeftMouse>' ],
|
||||
'delete': [ '<Del>' ],
|
||||
'set_value': [ '<C-CR>', '<leader><CR>' ]
|
||||
'set_value': [ '<C-CR>', '<leader><CR>' ],
|
||||
'read_memory': [ '<leader>m' ],
|
||||
},
|
||||
'stack_trace': {
|
||||
'expand_or_jump': [ '<CR>', '<2-LeftMouse>' ],
|
||||
|
|
|
|||
|
|
@ -56,6 +56,11 @@ class Expandable:
|
|||
def VariablesReference( self ):
|
||||
assert False
|
||||
|
||||
@abc.abstractmethod
|
||||
def MemoryReference( self ):
|
||||
assert None
|
||||
|
||||
|
||||
|
||||
class Scope( Expandable ):
|
||||
"""Holds an expandable scope (a DAP scope dict), with expand/collapse state"""
|
||||
|
|
@ -66,6 +71,9 @@ class Scope( Expandable ):
|
|||
def VariablesReference( self ):
|
||||
return self.scope.get( 'variablesReference', 0 )
|
||||
|
||||
def MemoryReference( self ):
|
||||
return None
|
||||
|
||||
def Update( self, scope ):
|
||||
self.scope = scope
|
||||
|
||||
|
|
@ -81,6 +89,9 @@ class WatchResult( Expandable ):
|
|||
def VariablesReference( self ):
|
||||
return self.result.get( 'variablesReference', 0 )
|
||||
|
||||
def MemoryReference( self ):
|
||||
return self.result.get( 'memoryReference' )
|
||||
|
||||
def Update( self, result ):
|
||||
self.changed = False
|
||||
if self.result[ 'result' ] != result[ 'result' ]:
|
||||
|
|
@ -105,6 +116,9 @@ class Variable( Expandable ):
|
|||
def VariablesReference( self ):
|
||||
return self.variable.get( 'variablesReference', 0 )
|
||||
|
||||
def MemoryReference( self ):
|
||||
return self.variable.get( 'memoryReference' )
|
||||
|
||||
def Update( self, variable ):
|
||||
self.changed = False
|
||||
if self.variable[ 'value' ] != variable[ 'value' ]:
|
||||
|
|
@ -163,6 +177,10 @@ def AddExpandMappings( mappings = None ):
|
|||
for mapping in utils.GetVimList( mappings, 'set_value' ):
|
||||
vim.command( f'nnoremap <silent> <buffer> { mapping } '
|
||||
':<C-u>call vimspector#SetVariableValue()<CR>' )
|
||||
for mapping in utils.GetVimList( mappings, 'read_memory' ):
|
||||
vim.command( f'nnoremap <silent> <buffer> { mapping } '
|
||||
':<C-u>call vimspector#ReadMemory()<CR>' )
|
||||
|
||||
|
||||
|
||||
class VariablesView( object ):
|
||||
|
|
@ -187,6 +205,8 @@ class VariablesView( object ):
|
|||
if utils.UseWinBar():
|
||||
vim.command( 'nnoremenu <silent> 1.1 WinBar.Set '
|
||||
':call vimspector#SetVariableValue()<CR>' )
|
||||
vim.command( 'nnoremenu <silent> 1.2 WinBar.Memory '
|
||||
':call vimspector#ReadMemory()<CR>' )
|
||||
AddExpandMappings( mappings )
|
||||
|
||||
# Set up the "Watches" buffer in the watches_win (and create a WinBar in
|
||||
|
|
@ -211,8 +231,10 @@ class VariablesView( object ):
|
|||
':call vimspector#ExpandVariable()<CR>' )
|
||||
vim.command( 'nnoremenu <silent> 1.3 WinBar.Delete '
|
||||
':call vimspector#DeleteWatch()<CR>' )
|
||||
vim.command( 'nnoremenu <silent> 1.1 WinBar.Set '
|
||||
vim.command( 'nnoremenu <silent> 1.4 WinBar.Set '
|
||||
':call vimspector#SetVariableValue()<CR>' )
|
||||
vim.command( 'nnoremenu <silent> 1.5 WinBar.Memory '
|
||||
':call vimspector#ReadMemory()<CR>' )
|
||||
|
||||
# Set the (global!) balloon expr if supported
|
||||
has_balloon = int( vim.eval( "has( 'balloon_eval' )" ) )
|
||||
|
|
@ -580,6 +602,14 @@ class VariablesView( object ):
|
|||
}, failure_handler = failure_handler )
|
||||
|
||||
|
||||
def GetMemoryReference( self, buf = None, line_num = None ):
|
||||
# Get a memoryReference for use in a ReadMemory request
|
||||
variable, _ = self._GetVariable( buf, line_num )
|
||||
if variable is None:
|
||||
return None
|
||||
|
||||
return variable.MemoryReference()
|
||||
|
||||
|
||||
def _DrawVariables( self, view, variables, indent, is_short = False ):
|
||||
assert indent > 0
|
||||
|
|
@ -595,10 +625,12 @@ class VariablesView( object ):
|
|||
value = variable.variable.get( 'value', '<unknown>' )
|
||||
)
|
||||
else:
|
||||
marker = 'm' if variable.MemoryReference() is not None else ' '
|
||||
marker += '*' if variable.changed else ' '
|
||||
text = '{indent}{marker}{icon} {name} ({type_}): {value}'.format(
|
||||
# We borrow 1 space of indent to draw the change marker
|
||||
indent = ' ' * ( indent - 1 ),
|
||||
marker = '*' if variable.changed else ' ',
|
||||
marker = marker,
|
||||
icon = '+' if ( variable.IsExpandable()
|
||||
and not variable.IsExpanded() ) else '-',
|
||||
name = variable.variable.get( 'name', '' ),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue