Improve output view; use jobs to display logs and remote commands
This commit is contained in:
parent
e006b15100
commit
bb3909c16f
4 changed files with 86 additions and 63 deletions
|
|
@ -211,7 +211,8 @@ class DebugSession( object ):
|
|||
def OnServerStderr( self, data ):
|
||||
self._logger.info( "Server stderr: %s", data )
|
||||
if self._outputView:
|
||||
self._outputView.ServerEcho( data )
|
||||
self._outputView.Print( 'server', data )
|
||||
|
||||
|
||||
def OnRequestTimeout( self, timer_id ):
|
||||
if self._connection:
|
||||
|
|
@ -461,11 +462,8 @@ class DebugSession( object ):
|
|||
for index, item in enumerate( cmd ):
|
||||
cmd[ index ] = item.replace( '%PID%', pid )
|
||||
|
||||
# TODO: Log files, etc. ?
|
||||
self._logger.debug( 'Running remote app: %s', cmd )
|
||||
self._attach_process = vim.eval(
|
||||
'vimspector#internal#job#RunCommand( {} )'.format(
|
||||
json.dumps( cmd ) ) )
|
||||
self._outputView.RunJobWithOutput( 'Remote', cmd )
|
||||
else:
|
||||
if atttach_config[ 'pidSelect' ] == 'ask':
|
||||
pid = utils.AskForInput( 'Enter PID to attach to: ' )
|
||||
|
|
@ -478,7 +476,7 @@ class DebugSession( object ):
|
|||
atttach_config[ 'pidSelect' ] ) )
|
||||
|
||||
|
||||
def _PrepareRun( self, adapter_config, launch_config ):
|
||||
def _PrepareLaunch( self, command_line, adapter_config, launch_config ):
|
||||
run_config = adapter_config.get( 'launch', {} )
|
||||
|
||||
if 'remote' in run_config:
|
||||
|
|
@ -490,10 +488,18 @@ class DebugSession( object ):
|
|||
ssh.append( remote[ 'host' ] )
|
||||
|
||||
cmd = ssh + remote[ 'runCommand' ][:]
|
||||
self._logger.debug( 'Running remote app: %s', cmd )
|
||||
self._attach_process = vim.eval(
|
||||
'vimspector#internal#job#RunCommand( {} )'.format(
|
||||
json.dumps( cmd ) ) )
|
||||
full_cmd = []
|
||||
for item in cmd:
|
||||
if isinstance( command_line, list ):
|
||||
if item == '%CMD%':
|
||||
full_cmd.extend( command_line )
|
||||
else:
|
||||
full_cmd.append( item )
|
||||
else:
|
||||
full_cmd.append( item.replace( '%CMD%', command_line ) )
|
||||
|
||||
self._logger.debug( 'Running remote app: %s', full_cmd )
|
||||
self._outputView.RunJobWithOutput( 'Remote', full_cmd )
|
||||
|
||||
|
||||
def _Initialise( self ):
|
||||
|
|
@ -518,17 +524,24 @@ class DebugSession( object ):
|
|||
def OnFailure( self, reason, message ):
|
||||
msg = "Request for '{}' failed: {}".format( message[ 'command' ],
|
||||
reason )
|
||||
self._outputView.ServerEcho( msg )
|
||||
self._outputView.Print( 'server', msg )
|
||||
|
||||
def _Launch( self ):
|
||||
self._logger.debug( "LAUNCH!" )
|
||||
adapter_config = self._adapter
|
||||
launch_config = self._configuration[ 'configuration' ]
|
||||
|
||||
if launch_config.get( 'request' ) == "attach":
|
||||
request = self._configuration.get(
|
||||
'remote-request',
|
||||
launch_config.get( 'request', 'launch' ) )
|
||||
|
||||
if request == "attach":
|
||||
self._PrepareAttach( adapter_config, launch_config )
|
||||
elif launch_config.get( 'request' ) == "run":
|
||||
self._PrepareRun( adapter_config, launch_config )
|
||||
elif request == "launch":
|
||||
# FIXME: This cmdLine hack is not fun.
|
||||
self._PrepareLaunch( self._configuration.get( 'remote-cmdLine', [] ),
|
||||
adapter_config,
|
||||
launch_config )
|
||||
|
||||
# FIXME: name is mandatory. Forcefully add it (we should really use the
|
||||
# _actual_ name, but that isn't actually remembered at this point)
|
||||
|
|
@ -730,6 +743,6 @@ class DebugSession( object ):
|
|||
utils.UserMessage( msg, persist = True )
|
||||
|
||||
if self._outputView:
|
||||
self._outputView.ServerEcho( msg )
|
||||
self._outputView.Print( 'server', msg )
|
||||
|
||||
self._stackTraceView.OnStopped( event )
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ class TabBuffer( object ):
|
|||
self.buf = buf
|
||||
self.index = index
|
||||
self.flag = False
|
||||
self.job = None
|
||||
self.is_job = False
|
||||
|
||||
|
||||
BUFFER_MAP = {
|
||||
|
|
@ -54,7 +54,7 @@ class OutputView( object ):
|
|||
|
||||
self._ShowOutput( 'Console' )
|
||||
|
||||
def ServerEcho( self, text ):
|
||||
def Print( self, categroy, text ):
|
||||
self._Print( 'server', text.splitlines() )
|
||||
|
||||
def OnOutput( self, event ):
|
||||
|
|
@ -93,12 +93,10 @@ class OutputView( object ):
|
|||
self.Clear()
|
||||
|
||||
def Clear( self ):
|
||||
for buf in self._buffers:
|
||||
vim.command( 'bwipeout! {0}'.format( self._buffers[ buf ].buf.name ) )
|
||||
|
||||
if 'Vimspector' in self._buffers:
|
||||
if self._buffers[ 'Vimspector' ].job is not None:
|
||||
utils.TerminateJob( self._buffers[ 'Vimspector' ].job )
|
||||
for category, tab_buffer in self._buffers.items():
|
||||
if tab_buffer.is_job:
|
||||
utils.CleanUpCommand( category )
|
||||
vim.command( 'bdelete! {0}'.format( tab_buffer.buf.number ) )
|
||||
|
||||
self._buffers.clear()
|
||||
|
||||
|
|
@ -113,6 +111,7 @@ class OutputView( object ):
|
|||
|
||||
def Evaluate( self, frame, expression ):
|
||||
if not frame:
|
||||
self.Print( 'Console', 'There is no current stack frame' )
|
||||
return
|
||||
|
||||
console = self._buffers[ 'Console' ].buf
|
||||
|
|
@ -144,17 +143,26 @@ class OutputView( object ):
|
|||
vim.current.window = self._window
|
||||
self._RenderWinBar( category )
|
||||
|
||||
def _CreateBuffer( self, category, file_name = None ):
|
||||
|
||||
def RunJobWithOutput( self, category, cmd ):
|
||||
self._CreateBuffer( category, cmd = cmd )
|
||||
|
||||
|
||||
def _CreateBuffer( self, category, file_name = None, cmd = None ):
|
||||
with utils.RestoreCurrentWindow():
|
||||
vim.current.window = self._window
|
||||
|
||||
with utils.RestoreCurrentBuffer( self._window ):
|
||||
|
||||
if file_name is not None:
|
||||
tab_buffer = TabBuffer( utils.BufferForFile( file_name ),
|
||||
len( self._buffers ) )
|
||||
tab_buffer.job = utils.SetUpTailBuffer( tab_buffer.buf, file_name )
|
||||
self._buffers[ category ] = tab_buffer
|
||||
assert cmd is None
|
||||
cmd = [ 'tail', '-F', '-n', '+1', '--', file_name ]
|
||||
|
||||
if cmd is not None:
|
||||
buf = utils.SetUpCommandBuffer( cmd, category )
|
||||
self._buffers[ category ] = TabBuffer( buf, len( self._buffers ) )
|
||||
self._buffers[ category ].is_job = True
|
||||
self._RenderWinBar( category )
|
||||
else:
|
||||
vim.command( 'enew' )
|
||||
tab_buffer = TabBuffer( vim.current.buffer, len( self._buffers ) )
|
||||
|
|
@ -170,7 +178,7 @@ class OutputView( object ):
|
|||
tab_buffer.buf,
|
||||
'vimspector.Output:{0}'.format( category ) )
|
||||
|
||||
self._RenderWinBar( category )
|
||||
self._RenderWinBar( category )
|
||||
|
||||
def _RenderWinBar( self, category ):
|
||||
tab_buffer = self._buffers[ category ]
|
||||
|
|
|
|||
|
|
@ -51,15 +51,39 @@ def OpenFileInCurrentWindow( file_name ):
|
|||
return vim.buffers[ buffer_number ]
|
||||
|
||||
|
||||
def SetUpTailBuffer( buf, path ):
|
||||
cmd = [ 'tail', '-F', '-n', '0', '--', path ]
|
||||
return vim.eval( 'job_start( {}, {{ "out_io": "buffer",'
|
||||
' "out_buf": {},'
|
||||
' "in_io": "null",'
|
||||
' "err_io": "null",'
|
||||
' "stoponexit": "term",'
|
||||
' "out_modifiable": 0 }} )'.format(
|
||||
json.dumps( cmd ), buf.number ) )
|
||||
def SetUpCommandBuffer( cmd, name ):
|
||||
vim.command(
|
||||
'let g:vimspector_command_job_{name} = job_start('
|
||||
' {cmd},'
|
||||
' {{'
|
||||
' "out_io": "buffer",'
|
||||
' "in_io": "null",'
|
||||
' "err_io": "buffer",'
|
||||
' "out_name": "_vimspector_log_{name}",'
|
||||
' "err_name": "_vimspector_log_{name}",'
|
||||
' "out_modifiable": 0,'
|
||||
' "err_modifiable": 0,'
|
||||
' "stoponexit": "term",'
|
||||
' }} )'.format( name = name,
|
||||
cmd = json.dumps( cmd ) ) )
|
||||
|
||||
stdout = vim.eval( 'ch_getbufnr( '
|
||||
' job_getchannel( g:vimspector_command_job_{name} ), '
|
||||
' "out"'
|
||||
')'.format( name = name ) )
|
||||
stderr = vim.eval( 'ch_getbufnr( '
|
||||
' job_getchannel( g:vimspector_command_job_{name} ), '
|
||||
' "err"'
|
||||
')'.format( name = name ) )
|
||||
|
||||
assert stdout == stderr
|
||||
return vim.buffers[ int( stdout ) ]
|
||||
|
||||
|
||||
def CleanUpCommand( name ):
|
||||
cmd = 'job_stop( g:vimspector_command_job_{name}, "kill" )'.format(
|
||||
name = name )
|
||||
vim.eval( cmd )
|
||||
|
||||
|
||||
def TerminateJob( job ):
|
||||
|
|
@ -253,14 +277,11 @@ def AppendToBuffer( buf, line_or_lines, modified=False ):
|
|||
else:
|
||||
line = 1
|
||||
buf[:] = line_or_lines
|
||||
except vim.error as e:
|
||||
except:
|
||||
# There seem to be a lot of Vim bugs that lead to E351, whose help says that
|
||||
# this is an internal error. Ignore the error, but write a trace to the log.
|
||||
if 'E315' in str( e ):
|
||||
logging.getLogger( __name__ ).exception(
|
||||
'Internal error while updating buffer' )
|
||||
else:
|
||||
raise e
|
||||
logging.getLogger( __name__ ).exception(
|
||||
'Internal error while updating buffer %s (%s)', buf.name, buf.number )
|
||||
finally:
|
||||
if not modified:
|
||||
buf.options[ 'modified' ] = False
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue