Manipulate buffers for variables, watches and stack trace
This commit is contained in:
parent
b049ba6d8d
commit
5ce4147361
3 changed files with 64 additions and 54 deletions
|
|
@ -39,10 +39,7 @@ class StackTraceView( object ):
|
|||
utils.SetUpScratchBuffer( self._buf, 'vimspector.StackTrace' )
|
||||
|
||||
vim.current.buffer = self._buf
|
||||
# FIXME: Remove all usage of "Windown" and just use buffers to prevent all
|
||||
# the bugs around the window being closed.
|
||||
self._win = vim.current.window
|
||||
utils.SetUpUIWindow( self._win )
|
||||
utils.SetUpUIWindow( vim.current.window )
|
||||
|
||||
vim.command( 'nnoremap <buffer> <CR> :call vimspector#GoToFrame()<CR>' )
|
||||
|
||||
|
|
@ -311,4 +308,4 @@ class StackTraceView( object ):
|
|||
def SetSyntax( self, syntax ):
|
||||
self._current_syntax = utils.SetSyntax( self._current_syntax,
|
||||
syntax,
|
||||
self._win )
|
||||
self._buf )
|
||||
|
|
|
|||
|
|
@ -194,6 +194,14 @@ def LetCurrentWindow( window ):
|
|||
yield
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def LetCurrentBuffer( buf ):
|
||||
with RestoreCursorPosition():
|
||||
with RestoreCurrentBuffer( vim.current.window ):
|
||||
vim.current.buffer = buf
|
||||
yield
|
||||
|
||||
|
||||
def JumpToWindow( window ):
|
||||
vim.current.tabpage = window.tabpage
|
||||
vim.current.window = window
|
||||
|
|
@ -555,8 +563,11 @@ def SetSyntax( current_syntax, syntax, *args ):
|
|||
if current_syntax == syntax:
|
||||
return
|
||||
|
||||
for win in args:
|
||||
with LetCurrentWindow( win ):
|
||||
for buf in args:
|
||||
with LetCurrentBuffer( buf ):
|
||||
# We use set syn= because just setting vim.Buffer.options[ 'syntax' ]
|
||||
# doesn't actually trigger the Syntax autocommand, and i'm not sure that
|
||||
# 'doautocmd Syntax' is the right solution or not
|
||||
vim.command( 'set syntax={}'.format( Escape( syntax ) ) )
|
||||
|
||||
return syntax
|
||||
|
|
|
|||
|
|
@ -16,15 +16,11 @@
|
|||
import abc
|
||||
import vim
|
||||
import logging
|
||||
from collections import namedtuple
|
||||
from functools import partial
|
||||
import typing
|
||||
|
||||
from vimspector import utils
|
||||
|
||||
View = namedtuple( 'View', [ 'win', 'lines', 'draw' ] )
|
||||
|
||||
|
||||
|
||||
class Expandable:
|
||||
"""Base for anything which might contain a hierarchy of values represented by
|
||||
|
|
@ -104,7 +100,6 @@ class Variable( Expandable ):
|
|||
self.variable = variable
|
||||
|
||||
|
||||
|
||||
class Watch:
|
||||
"""Holds a user watch expression (DAP request) and the result (WatchResult)"""
|
||||
def __init__( self, expression: dict ):
|
||||
|
|
@ -114,29 +109,44 @@ class Watch:
|
|||
self.result = None
|
||||
|
||||
|
||||
class View:
|
||||
lines: typing.Dict[ int, Expandable ]
|
||||
draw: typing.Callable
|
||||
buf: vim.Buffer
|
||||
|
||||
def __init__( self, win: vim.Window, lines, draw ):
|
||||
self.lines = lines
|
||||
self.draw = draw
|
||||
self.buf = win.buffer
|
||||
|
||||
utils.SetUpUIWindow( win )
|
||||
|
||||
|
||||
class VariablesView( object ):
|
||||
def __init__( self, connection, variables_win, watches_win ):
|
||||
self._logger = logging.getLogger( __name__ )
|
||||
utils.SetUpLogging( self._logger )
|
||||
|
||||
self._vars = View( variables_win, {}, self._DrawScopes )
|
||||
self._watch = View( watches_win, {}, self._DrawWatches )
|
||||
self._connection = connection
|
||||
self._current_syntax = ''
|
||||
|
||||
# Allows us to hit <CR> to expand/collapse variables
|
||||
with utils.LetCurrentWindow( self._vars.win ):
|
||||
# Set up the "Variables" buffer in the variables_win
|
||||
self._scopes: typing.List[ Scope ] = []
|
||||
self._vars = View( variables_win, {}, self._DrawScopes )
|
||||
utils.SetUpScratchBuffer( self._vars.buf, 'vimspector.Variables' )
|
||||
with utils.LetCurrentWindow( variables_win ):
|
||||
vim.command(
|
||||
'nnoremap <buffer> <CR> :call vimspector#ExpandVariable()<CR>' )
|
||||
|
||||
# List of current scopes of type Scope
|
||||
self._scopes: typing.List[ 'Scope' ] = []
|
||||
|
||||
# List of current Watches of type Watch
|
||||
self._watches: typing.List[ 'Watch' ] = []
|
||||
|
||||
# Allows us to hit <CR> to expand/collapse variables
|
||||
with utils.LetCurrentWindow( self._watch.win ):
|
||||
# Set up the "Watches" buffer in the watches_win (and create a WinBar in
|
||||
# there)
|
||||
self._watches: typing.List[ Watch ] = []
|
||||
self._watch = View( watches_win, {}, self._DrawWatches )
|
||||
utils.SetUpPromptBuffer( self._watch.buf,
|
||||
'vimspector.Watches',
|
||||
'Expression: ',
|
||||
'vimspector#AddWatchPrompt' )
|
||||
with utils.LetCurrentWindow( watches_win ):
|
||||
vim.command(
|
||||
'nnoremap <buffer> <CR> :call vimspector#ExpandVariable()<CR>' )
|
||||
vim.command(
|
||||
|
|
@ -149,15 +159,7 @@ class VariablesView( object ):
|
|||
vim.command( 'nnoremenu 1.3 WinBar.Delete '
|
||||
':call vimspector#DeleteWatch()<CR>' )
|
||||
|
||||
utils.SetUpScratchBuffer( self._vars.win.buffer, 'vimspector.Variables' )
|
||||
utils.SetUpPromptBuffer( self._watch.win.buffer,
|
||||
'vimspector.Watches',
|
||||
'Expression: ',
|
||||
'vimspector#AddWatchPrompt' )
|
||||
|
||||
utils.SetUpUIWindow( self._vars.win )
|
||||
utils.SetUpUIWindow( self._watch.win )
|
||||
|
||||
# Set the (global!) balloon expr if supported
|
||||
has_balloon = int( vim.eval( "has( 'balloon_eval' )" ) )
|
||||
has_balloon_term = int( vim.eval( "has( 'balloon_eval_term' )" ) )
|
||||
|
||||
|
|
@ -181,10 +183,10 @@ class VariablesView( object ):
|
|||
self._is_term = not bool( int( vim.eval( "has( 'gui_running' )" ) ) )
|
||||
|
||||
def Clear( self ):
|
||||
with utils.ModifiableScratchBuffer( self._vars.win.buffer ):
|
||||
utils.ClearBuffer( self._vars.win.buffer )
|
||||
with utils.ModifiableScratchBuffer( self._watch.win.buffer ):
|
||||
utils.ClearBuffer( self._watch.win.buffer )
|
||||
with utils.ModifiableScratchBuffer( self._vars.buf ):
|
||||
utils.ClearBuffer( self._vars.buf )
|
||||
with utils.ModifiableScratchBuffer( self._watch.buf ):
|
||||
utils.ClearBuffer( self._watch.buf )
|
||||
self._current_syntax = ''
|
||||
|
||||
def ConnectionUp( self, connection ):
|
||||
|
|
@ -198,8 +200,8 @@ class VariablesView( object ):
|
|||
for k, v in self._oldoptions.items():
|
||||
vim.options[ k ] = v
|
||||
|
||||
vim.command( 'bdelete! ' + str( self._watch.win.buffer.number ) )
|
||||
vim.command( 'bdelete! ' + str( self._vars.win.buffer.number ) )
|
||||
vim.command( 'bdelete! ' + str( self._watch.buf.number ) )
|
||||
vim.command( 'bdelete! ' + str( self._vars.buf.number ) )
|
||||
|
||||
def LoadScopes( self, frame ):
|
||||
def scopes_consumer( message ):
|
||||
|
|
@ -256,8 +258,8 @@ class VariablesView( object ):
|
|||
self.EvaluateWatches()
|
||||
|
||||
def DeleteWatch( self ):
|
||||
if vim.current.window != self._watch.win:
|
||||
utils.UserMessage( 'Not a watch window' )
|
||||
if vim.current.buffer != self._watch.buf:
|
||||
utils.UserMessage( 'Not a watch buffer' )
|
||||
return
|
||||
|
||||
current_line = vim.current.window.cursor[ 0 ]
|
||||
|
|
@ -305,9 +307,9 @@ class VariablesView( object ):
|
|||
self._DrawWatches()
|
||||
|
||||
def ExpandVariable( self ):
|
||||
if vim.current.window == self._vars.win:
|
||||
if vim.current.buffer == self._vars.buf:
|
||||
view = self._vars
|
||||
elif vim.current.window == self._watch.win:
|
||||
elif vim.current.buffer == self._watch.buf:
|
||||
view = self._watch
|
||||
else:
|
||||
return
|
||||
|
|
@ -341,7 +343,7 @@ class VariablesView( object ):
|
|||
assert indent > 0
|
||||
for variable in variables:
|
||||
line = utils.AppendToBuffer(
|
||||
view.win.buffer,
|
||||
view.buf,
|
||||
'{indent}{marker}{icon} {name} ({type_}): {value}'.format(
|
||||
# We borrow 1 space of indent to draw the change marker
|
||||
indent = ' ' * ( indent - 1 ),
|
||||
|
|
@ -363,8 +365,8 @@ class VariablesView( object ):
|
|||
# However it is pretty inefficient.
|
||||
self._vars.lines.clear()
|
||||
with utils.RestoreCursorPosition():
|
||||
with utils.ModifiableScratchBuffer( self._vars.win.buffer ):
|
||||
utils.ClearBuffer( self._vars.win.buffer )
|
||||
with utils.ModifiableScratchBuffer( self._vars.buf ):
|
||||
utils.ClearBuffer( self._vars.buf )
|
||||
for scope in self._scopes:
|
||||
self._DrawScope( 0, scope )
|
||||
|
||||
|
|
@ -374,11 +376,11 @@ class VariablesView( object ):
|
|||
# However it is pretty inefficient.
|
||||
self._watch.lines.clear()
|
||||
with utils.RestoreCursorPosition():
|
||||
with utils.ModifiableScratchBuffer( self._watch.win.buffer ):
|
||||
utils.ClearBuffer( self._watch.win.buffer )
|
||||
utils.AppendToBuffer( self._watch.win.buffer, 'Watches: ----' )
|
||||
with utils.ModifiableScratchBuffer( self._watch.buf ):
|
||||
utils.ClearBuffer( self._watch.buf )
|
||||
utils.AppendToBuffer( self._watch.buf, 'Watches: ----' )
|
||||
for watch in self._watches:
|
||||
line = utils.AppendToBuffer( self._watch.win.buffer,
|
||||
line = utils.AppendToBuffer( self._watch.buf,
|
||||
'Expression: '
|
||||
+ watch.expression[ 'expression' ] )
|
||||
watch.line = line
|
||||
|
|
@ -387,7 +389,7 @@ class VariablesView( object ):
|
|||
def _DrawScope( self, indent, scope ):
|
||||
icon = '+' if scope.IsExpandable() and not scope.IsExpandedByUser() else '-'
|
||||
|
||||
line = utils.AppendToBuffer( self._vars.win.buffer,
|
||||
line = utils.AppendToBuffer( self._vars.buf,
|
||||
'{0}{1} Scope: {2}'.format(
|
||||
' ' * indent,
|
||||
icon,
|
||||
|
|
@ -413,7 +415,7 @@ class VariablesView( object ):
|
|||
icon = icon,
|
||||
result = watch.result.result.get( 'result', '<unknown>' ) )
|
||||
|
||||
line = utils.AppendToBuffer( self._watch.win.buffer, line.split( '\n' ) )
|
||||
line = utils.AppendToBuffer( self._watch.buf, line.split( '\n' ) )
|
||||
self._watch.lines[ line ] = watch.result
|
||||
|
||||
if watch.result.ShouldDrawDrillDown():
|
||||
|
|
@ -495,7 +497,7 @@ class VariablesView( object ):
|
|||
def SetSyntax( self, syntax ):
|
||||
self._current_syntax = utils.SetSyntax( self._current_syntax,
|
||||
syntax,
|
||||
self._vars.win,
|
||||
self._watch.win )
|
||||
self._vars.buf,
|
||||
self._watch.buf )
|
||||
|
||||
# vim: sw=2
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue