Allow ctrl-c to cancel when asked for a variable
This commit is contained in:
parent
47ace82364
commit
99b582378a
5 changed files with 91 additions and 49 deletions
|
|
@ -137,14 +137,16 @@ function! vimspector#ListBreakpoints() abort
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! vimspector#CompleteOutput( ArgLead, CmdLine, CursorPos ) abort
|
function! vimspector#CompleteOutput( ArgLead, CmdLine, CursorPos ) abort
|
||||||
let buffers = py3eval( '_vimspector_session.GetOutputBuffers()' )
|
let buffers = py3eval( '_vimspector_session.GetOutputBuffers() '
|
||||||
|
\ . ' if _vimspector_session else []' )
|
||||||
return join( buffers, "\n" )
|
return join( buffers, "\n" )
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! vimspector#CompleteExpr( ArgLead, CmdLine, CursorPos ) abort
|
function! vimspector#CompleteExpr( ArgLead, CmdLine, CursorPos ) abort
|
||||||
return join( py3eval( '_vimspector_session.GetCompletionsSync( '
|
return join( py3eval( '_vimspector_session.GetCompletionsSync( '
|
||||||
\.' vim.eval( "a:CmdLine" ),'
|
\.' vim.eval( "a:CmdLine" ),'
|
||||||
\.' int( vim.eval( "a:CursorPos" ) ) )' ),
|
\.' int( vim.eval( "a:CursorPos" ) ) )'
|
||||||
|
\. ' if _vimspector_session else []' ),
|
||||||
\ "\n" )
|
\ "\n" )
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -342,11 +342,14 @@ class ProjectBreakpoints( object ):
|
||||||
f"Invalid value for exception breakpoint filter '{f}': "
|
f"Invalid value for exception breakpoint filter '{f}': "
|
||||||
f"'{result}'. Must be boolean, 'Y', 'N' or '' (default)" )
|
f"'{result}'. Must be boolean, 'Y', 'N' or '' (default)" )
|
||||||
else:
|
else:
|
||||||
result = utils.AskForInput(
|
try:
|
||||||
"{}: Break on {} (Y/N/default: {})? ".format( f[ 'filter' ],
|
result = utils.AskForInput(
|
||||||
f[ 'label' ],
|
"{}: Break on {} (Y/N/default: {})? ".format( f[ 'filter' ],
|
||||||
default_value ),
|
f[ 'label' ],
|
||||||
default_value )
|
default_value ),
|
||||||
|
default_value )
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
result = ''
|
||||||
|
|
||||||
if result == 'Y':
|
if result == 'Y':
|
||||||
exception_filters.append( f[ 'filter' ] )
|
exception_filters.append( f[ 'filter' ] )
|
||||||
|
|
|
||||||
|
|
@ -215,26 +215,30 @@ class DebugSession( object ):
|
||||||
USER_CHOICES.update( launch_variables )
|
USER_CHOICES.update( launch_variables )
|
||||||
variables.update( launch_variables )
|
variables.update( launch_variables )
|
||||||
|
|
||||||
variables.update(
|
try:
|
||||||
utils.ParseVariables( adapter.get( 'variables', {} ),
|
variables.update(
|
||||||
variables,
|
utils.ParseVariables( adapter.get( 'variables', {} ),
|
||||||
calculus,
|
variables,
|
||||||
USER_CHOICES ) )
|
calculus,
|
||||||
variables.update(
|
USER_CHOICES ) )
|
||||||
utils.ParseVariables( configuration.get( 'variables', {} ),
|
variables.update(
|
||||||
variables,
|
utils.ParseVariables( configuration.get( 'variables', {} ),
|
||||||
calculus,
|
variables,
|
||||||
USER_CHOICES ) )
|
calculus,
|
||||||
|
USER_CHOICES ) )
|
||||||
|
|
||||||
|
|
||||||
utils.ExpandReferencesInDict( configuration,
|
utils.ExpandReferencesInDict( configuration,
|
||||||
variables,
|
variables,
|
||||||
calculus,
|
calculus,
|
||||||
USER_CHOICES )
|
USER_CHOICES )
|
||||||
utils.ExpandReferencesInDict( adapter,
|
utils.ExpandReferencesInDict( adapter,
|
||||||
variables,
|
variables,
|
||||||
calculus,
|
calculus,
|
||||||
USER_CHOICES )
|
USER_CHOICES )
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
self._Reset()
|
||||||
|
return
|
||||||
|
|
||||||
if not adapter:
|
if not adapter:
|
||||||
utils.UserMessage( 'No adapter configured for {}'.format(
|
utils.UserMessage( 'No adapter configured for {}'.format(
|
||||||
|
|
@ -294,18 +298,35 @@ class DebugSession( object ):
|
||||||
|
|
||||||
self._StartWithConfiguration( self._configuration, self._adapter )
|
self._StartWithConfiguration( self._configuration, self._adapter )
|
||||||
|
|
||||||
def IfConnected( fct ):
|
def IfConnected( otherwise=None ):
|
||||||
|
def decorator( fct ):
|
||||||
|
"""Decorator, call fct if self._connected else echo warning"""
|
||||||
|
@functools.wraps( fct )
|
||||||
|
def wrapper( self, *args, **kwargs ):
|
||||||
|
if not self._connection:
|
||||||
|
utils.UserMessage(
|
||||||
|
'Vimspector not connected, start a debug session first',
|
||||||
|
persist=False,
|
||||||
|
error=True )
|
||||||
|
return otherwise
|
||||||
|
return fct( self, *args, **kwargs )
|
||||||
|
return wrapper
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
def RequiresUI( otherwise=None ):
|
||||||
"""Decorator, call fct if self._connected else echo warning"""
|
"""Decorator, call fct if self._connected else echo warning"""
|
||||||
@functools.wraps( fct )
|
def decorator( fct ):
|
||||||
def wrapper( self, *args, **kwargs ):
|
@functools.wraps( fct )
|
||||||
if not self._connection:
|
def wrapper( self, *args, **kwargs ):
|
||||||
utils.UserMessage(
|
if not self._uiTab or not self._uiTab.valid:
|
||||||
'Vimspector not connected, start a debug session first',
|
utils.UserMessage(
|
||||||
persist=True,
|
'Vimspector is not active',
|
||||||
error=True )
|
persist=False,
|
||||||
return
|
error=True )
|
||||||
return fct( self, *args, **kwargs )
|
return otherwise
|
||||||
return wrapper
|
return fct( self, *args, **kwargs )
|
||||||
|
return wrapper
|
||||||
|
return decorator
|
||||||
|
|
||||||
def OnChannelData( self, data ):
|
def OnChannelData( self, data ):
|
||||||
if self._connection is None:
|
if self._connection is None:
|
||||||
|
|
@ -328,7 +349,7 @@ class DebugSession( object ):
|
||||||
# TODO: Not calld
|
# TODO: Not calld
|
||||||
self._connection = None
|
self._connection = None
|
||||||
|
|
||||||
@IfConnected
|
@IfConnected()
|
||||||
def Stop( self ):
|
def Stop( self ):
|
||||||
self._logger.debug( "Stop debug adapter with no callback" )
|
self._logger.debug( "Stop debug adapter with no callback" )
|
||||||
self._StopDebugAdapter()
|
self._StopDebugAdapter()
|
||||||
|
|
@ -365,7 +386,7 @@ class DebugSession( object ):
|
||||||
# make sure that we're displaying signs in any still-open buffers
|
# make sure that we're displaying signs in any still-open buffers
|
||||||
self._breakpoints.UpdateUI()
|
self._breakpoints.UpdateUI()
|
||||||
|
|
||||||
@IfConnected
|
@IfConnected()
|
||||||
def StepOver( self ):
|
def StepOver( self ):
|
||||||
if self._stackTraceView.GetCurrentThreadId() is None:
|
if self._stackTraceView.GetCurrentThreadId() is None:
|
||||||
return
|
return
|
||||||
|
|
@ -377,7 +398,7 @@ class DebugSession( object ):
|
||||||
},
|
},
|
||||||
} )
|
} )
|
||||||
|
|
||||||
@IfConnected
|
@IfConnected()
|
||||||
def StepInto( self ):
|
def StepInto( self ):
|
||||||
if self._stackTraceView.GetCurrentThreadId() is None:
|
if self._stackTraceView.GetCurrentThreadId() is None:
|
||||||
return
|
return
|
||||||
|
|
@ -389,7 +410,7 @@ class DebugSession( object ):
|
||||||
},
|
},
|
||||||
} )
|
} )
|
||||||
|
|
||||||
@IfConnected
|
@IfConnected()
|
||||||
def StepOut( self ):
|
def StepOut( self ):
|
||||||
if self._stackTraceView.GetCurrentThreadId() is None:
|
if self._stackTraceView.GetCurrentThreadId() is None:
|
||||||
return
|
return
|
||||||
|
|
@ -407,29 +428,29 @@ class DebugSession( object ):
|
||||||
else:
|
else:
|
||||||
self.Start()
|
self.Start()
|
||||||
|
|
||||||
@IfConnected
|
@IfConnected()
|
||||||
def Pause( self ):
|
def Pause( self ):
|
||||||
self._stackTraceView.Pause()
|
self._stackTraceView.Pause()
|
||||||
|
|
||||||
@IfConnected
|
@IfConnected()
|
||||||
def ExpandVariable( self ):
|
def ExpandVariable( self ):
|
||||||
self._variablesView.ExpandVariable()
|
self._variablesView.ExpandVariable()
|
||||||
|
|
||||||
@IfConnected
|
@IfConnected()
|
||||||
def AddWatch( self, expression ):
|
def AddWatch( self, expression ):
|
||||||
self._variablesView.AddWatch( self._stackTraceView.GetCurrentFrame(),
|
self._variablesView.AddWatch( self._stackTraceView.GetCurrentFrame(),
|
||||||
expression )
|
expression )
|
||||||
|
|
||||||
@IfConnected
|
@IfConnected()
|
||||||
def EvaluateConsole( self, expression ):
|
def EvaluateConsole( self, expression ):
|
||||||
self._outputView.Evaluate( self._stackTraceView.GetCurrentFrame(),
|
self._outputView.Evaluate( self._stackTraceView.GetCurrentFrame(),
|
||||||
expression )
|
expression )
|
||||||
|
|
||||||
@IfConnected
|
@IfConnected()
|
||||||
def DeleteWatch( self ):
|
def DeleteWatch( self ):
|
||||||
self._variablesView.DeleteWatch()
|
self._variablesView.DeleteWatch()
|
||||||
|
|
||||||
@IfConnected
|
@IfConnected()
|
||||||
def ShowBalloon( self, winnr, expression ):
|
def ShowBalloon( self, winnr, expression ):
|
||||||
"""Proxy: ballonexpr -> variables.ShowBallon"""
|
"""Proxy: ballonexpr -> variables.ShowBallon"""
|
||||||
frame = self._stackTraceView.GetCurrentFrame()
|
frame = self._stackTraceView.GetCurrentFrame()
|
||||||
|
|
@ -448,10 +469,11 @@ class DebugSession( object ):
|
||||||
# Return variable aware function
|
# Return variable aware function
|
||||||
return self._variablesView.ShowBalloon( frame, expression )
|
return self._variablesView.ShowBalloon( frame, expression )
|
||||||
|
|
||||||
@IfConnected
|
@IfConnected()
|
||||||
def ExpandFrameOrThread( self ):
|
def ExpandFrameOrThread( self ):
|
||||||
self._stackTraceView.ExpandFrameOrThread()
|
self._stackTraceView.ExpandFrameOrThread()
|
||||||
|
|
||||||
|
@RequiresUI()
|
||||||
def ShowOutput( self, category ):
|
def ShowOutput( self, category ):
|
||||||
if not self._outputView.WindowIsValid():
|
if not self._outputView.WindowIsValid():
|
||||||
# TODO: The UI code is too scattered. Re-organise into a UI class that
|
# TODO: The UI code is too scattered. Re-organise into a UI class that
|
||||||
|
|
@ -468,10 +490,11 @@ class DebugSession( object ):
|
||||||
|
|
||||||
self._outputView.ShowOutput( category )
|
self._outputView.ShowOutput( category )
|
||||||
|
|
||||||
|
@RequiresUI( otherwise=[] )
|
||||||
def GetOutputBuffers( self ):
|
def GetOutputBuffers( self ):
|
||||||
return self._outputView.GetCategories()
|
return self._outputView.GetCategories()
|
||||||
|
|
||||||
@IfConnected
|
@IfConnected( otherwise=[] )
|
||||||
def GetCompletionsSync( self, text_line, column_in_bytes ):
|
def GetCompletionsSync( self, text_line, column_in_bytes ):
|
||||||
if not self._server_capabilities.get( 'supportsCompletionsRequest' ):
|
if not self._server_capabilities.get( 'supportsCompletionsRequest' ):
|
||||||
return []
|
return []
|
||||||
|
|
@ -552,9 +575,11 @@ class DebugSession( object ):
|
||||||
vim.command( 'doautocmd User VimspectorUICreated' )
|
vim.command( 'doautocmd User VimspectorUICreated' )
|
||||||
|
|
||||||
|
|
||||||
|
@RequiresUI()
|
||||||
def ClearCurrentFrame( self ):
|
def ClearCurrentFrame( self ):
|
||||||
self.SetCurrentFrame( None )
|
self.SetCurrentFrame( None )
|
||||||
|
|
||||||
|
@RequiresUI()
|
||||||
def SetCurrentFrame( self, frame ):
|
def SetCurrentFrame( self, frame ):
|
||||||
if not frame:
|
if not frame:
|
||||||
self._stackTraceView.Clear()
|
self._stackTraceView.Clear()
|
||||||
|
|
@ -596,6 +621,9 @@ class DebugSession( object ):
|
||||||
|
|
||||||
if self._adapter[ 'port' ] == 'ask':
|
if self._adapter[ 'port' ] == 'ask':
|
||||||
port = utils.AskForInput( 'Enter port to connect to: ' )
|
port = utils.AskForInput( 'Enter port to connect to: ' )
|
||||||
|
if port is None:
|
||||||
|
self._Reset()
|
||||||
|
return
|
||||||
self._adapter[ 'port' ] = port
|
self._adapter[ 'port' ] = port
|
||||||
|
|
||||||
self._connection_type = self._api_prefix + self._connection_type
|
self._connection_type = self._api_prefix + self._connection_type
|
||||||
|
|
@ -705,6 +733,8 @@ class DebugSession( object ):
|
||||||
prop = atttach_config[ 'pidProperty' ]
|
prop = atttach_config[ 'pidProperty' ]
|
||||||
if prop not in launch_config:
|
if prop not in launch_config:
|
||||||
pid = utils.AskForInput( 'Enter PID to attach to: ' )
|
pid = utils.AskForInput( 'Enter PID to attach to: ' )
|
||||||
|
if pid is None:
|
||||||
|
return
|
||||||
launch_config[ prop ] = pid
|
launch_config[ prop ] = pid
|
||||||
return
|
return
|
||||||
elif atttach_config[ 'pidSelect' ] == 'none':
|
elif atttach_config[ 'pidSelect' ] == 'none':
|
||||||
|
|
|
||||||
|
|
@ -339,7 +339,7 @@ def AskForInput( prompt, default_value = None ):
|
||||||
return vim.eval( "input( '{}' {} )".format( Escape( prompt ),
|
return vim.eval( "input( '{}' {} )".format( Escape( prompt ),
|
||||||
default_option ) )
|
default_option ) )
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
return ''
|
return None
|
||||||
|
|
||||||
|
|
||||||
def AppendToBuffer( buf, line_or_lines, modified=False ):
|
def AppendToBuffer( buf, line_or_lines, modified=False ):
|
||||||
|
|
@ -447,6 +447,10 @@ def ExpandReferencesInString( orig_s,
|
||||||
default_value = user_choices.get( key, None )
|
default_value = user_choices.get( key, None )
|
||||||
mapping[ key ] = AskForInput( 'Enter value for {}: '.format( key ),
|
mapping[ key ] = AskForInput( 'Enter value for {}: '.format( key ),
|
||||||
default_value )
|
default_value )
|
||||||
|
|
||||||
|
if mapping[ key ] is None:
|
||||||
|
raise KeyboardInterrupt
|
||||||
|
|
||||||
user_choices[ key ] = mapping[ key ]
|
user_choices[ key ] = mapping[ key ]
|
||||||
_logger.debug( "Value for %s not set in %s (from %s): set to %s",
|
_logger.debug( "Value for %s not set in %s (from %s): set to %s",
|
||||||
key,
|
key,
|
||||||
|
|
|
||||||
|
|
@ -332,6 +332,9 @@ function! Test_CloseOutput_Early()
|
||||||
" 1 screen row, so g:vimspector_bottombar_height -1
|
" 1 screen row, so g:vimspector_bottombar_height -1
|
||||||
call assert_equal( 4, winheight( g:vimspector_session_windows.output ) )
|
call assert_equal( 4, winheight( g:vimspector_session_windows.output ) )
|
||||||
|
|
||||||
|
call vimspector#StepOver()
|
||||||
|
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 26, 1 )
|
||||||
|
|
||||||
au! TestCustomUI
|
au! TestCustomUI
|
||||||
call vimspector#test#setup#Reset()
|
call vimspector#test#setup#Reset()
|
||||||
%bwipe!
|
%bwipe!
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue