Launch remote commands in a termianl

This allows stdin and mans you don't need the output window visible to
see the useful process output when debugging a remote-Launch.
This commit is contained in:
Ben Jackson 2020-09-23 12:29:40 +01:00 committed by Ben Jackson
commit 6fd4724189
3 changed files with 116 additions and 80 deletions

View file

@ -18,7 +18,7 @@ import logging
import json
from collections import defaultdict
from vimspector import utils, settings, signs
from vimspector import utils, terminal, signs
class CodeView( object ):
@ -26,8 +26,7 @@ class CodeView( object ):
self._window = window
self._api_prefix = api_prefix
self._terminal_window = None
self._terminal_buffer_number = None
self._terminal = None
self.current_syntax = None
self._logger = logging.getLogger( __name__ )
@ -63,7 +62,9 @@ class CodeView( object ):
linehl = 'CursorLine' )
def _UndisplayPC( self ):
def _UndisplayPC( self, clear_pc = True ):
if clear_pc:
self._current_frame = None
if self._signs[ 'vimspectorPC' ]:
signs.UnplaceSign( self._signs[ 'vimspectorPC' ], 'VimspectorCode' )
self._signs[ 'vimspectorPC' ] = None
@ -74,7 +75,7 @@ class CodeView( object ):
if not frame:
return
self._UndisplayPC()
self._UndisplayPC( clear_pc = False )
# FIXME: Do we relly need to keep using up IDs ?
self._signs[ 'vimspectorPC' ] = self._next_sign_id
@ -152,7 +153,7 @@ class CodeView( object ):
signs.UnplaceSign( self._signs[ 'vimspectorPC' ], 'VimspectorCode' )
self._signs[ 'vimspectorPC' ] = None
self._current_frame = None
self._UndisplayPC()
self._UndisplaySigns()
self.current_syntax = None
@ -241,73 +242,11 @@ class CodeView( object ):
def LaunchTerminal( self, params ):
# kind = params.get( 'kind', 'integrated' )
self._terminal = terminal.LaunchTerminal( self._api_prefix,
params,
window_for_start = self._window,
existing_term = self._terminal )
# FIXME: We don't support external terminals, and only open in the
# integrated one.
cwd = params[ 'cwd' ]
args = params[ 'args' ]
env = params.get( 'env', {} )
term_options = {
'vertical': 1,
'norestore': 1,
'cwd': cwd,
'env': env,
}
if self._window.valid:
window_for_start = self._window
else:
# TOOD: Where? Maybe we should just use botright vertical ...
window_for_start = vim.current.window
if self._terminal_window is not None and self._terminal_window.valid:
assert self._terminal_buffer_number
window_for_start = self._terminal_window
if ( self._terminal_window.buffer.number == self._terminal_buffer_number
and int( utils.Call( 'vimspector#internal#{}term#IsFinished'.format(
self._api_prefix ),
self._terminal_buffer_number ) ) ):
term_options[ 'curwin' ] = 1
else:
term_options[ 'vertical' ] = 0
buffer_number = None
terminal_window = None
with utils.LetCurrentWindow( window_for_start ):
# If we're making a vertical split from the code window, make it no more
# than 80 columns and no fewer than 10. Also try and keep the code window
# at least 82 columns
if term_options[ 'vertical' ] and not term_options.get( 'curwin', 0 ):
term_options[ 'term_cols' ] = max(
min ( int( vim.eval( 'winwidth( 0 )' ) )
- settings.Int( 'code_minwidth' ),
settings.Int( 'terminal_maxwidth' ) ),
settings.Int( 'terminal_minwidth' )
)
buffer_number = int(
utils.Call(
'vimspector#internal#{}term#Start'.format( self._api_prefix ),
args,
term_options ) )
terminal_window = vim.current.window
if buffer_number is None or buffer_number <= 0:
# TODO: Do something better like reject the request?
raise ValueError( "Unable to start terminal" )
self._terminal_window = terminal_window
self._terminal_buffer_number = buffer_number
vim.vars[ 'vimspector_session_windows' ][ 'terminal' ] = utils.WindowID(
self._terminal_window,
vim.current.tabpage )
with utils.RestoreCursorPosition():
with utils.RestoreCurrentWindow():
with utils.RestoreCurrentBuffer( vim.current.window ):
vim.command( 'doautocmd User VimspectorTerminalOpened' )
return buffer_number
# FIXME: Change this tor return the PID rather than having debug_session
# work that out
return self._terminal.buffer_number

View file

@ -31,6 +31,7 @@ from vimspector import ( breakpoints,
utils,
variables,
settings,
terminal,
installer )
from vimspector.vendor.json_minify import minify
@ -61,6 +62,7 @@ class DebugSession( object ):
self._outputView = None
self._breakpoints = breakpoints.ProjectBreakpoints()
self._splash_screen = None
self._remote_term = None
self._run_on_server_exit = None
@ -360,7 +362,6 @@ class DebugSession( object ):
def OnServerStderr( self, data ):
self._logger.info( "Server stderr: %s", data )
if self._outputView:
self._outputView.Print( 'server', data )
@ -404,6 +405,7 @@ class DebugSession( object ):
self._variablesView = None
self._outputView = None
self._codeView = None
self._remote_term = None
self._uiTab = None
# make sure that we're displaying signs in any still-open buffers
@ -760,13 +762,20 @@ class DebugSession( object ):
commands = self._GetCommands( remote, 'attach' )
for command in commands:
cmd = remote_exec_cmd + command[ : ]
cmd = remote_exec_cmd + command
for index, item in enumerate( cmd ):
cmd[ index ] = item.replace( '%PID%', pid )
self._logger.debug( 'Running remote app: %s', cmd )
self._outputView.RunJobWithOutput( 'Remote', cmd )
self._remote_term = terminal.LaunchTerminal(
self._api_prefix,
{
'args': cmd,
'cwd': os.getcwd()
},
self._codeView._window,
self._remote_term )
else:
if atttach_config[ 'pidSelect' ] == 'ask':
prop = atttach_config[ 'pidProperty' ]
@ -805,8 +814,14 @@ class DebugSession( object ):
full_cmd.append( item.replace( '%CMD%', command_line ) )
self._logger.debug( 'Running remote app: %s', full_cmd )
self._outputView.RunJobWithOutput( 'Remote{}'.format( index ),
full_cmd )
self._remote_term = terminal.LaunchTerminal(
self._api_prefix,
{
'args': full_cmd,
'cwd': os.getcwd()
},
self._codeView._window,
self._remote_term )
def _GetSSHCommand( self, remote ):

View file

@ -0,0 +1,82 @@
from vimspector import utils, settings
import vim
class Terminal:
window = None
buffer_number: int = None
def LaunchTerminal( api_prefix,
params,
window_for_start,
existing_term ):
if not existing_term:
term = Terminal()
else:
term = existing_term
cwd = params[ 'cwd' ]
args = params[ 'args' ]
env = params.get( 'env', {} )
term_options = {
'vertical': 1,
'norestore': 1,
'cwd': cwd,
'env': env,
}
if not window_for_start or not window_for_start.valid:
# TOOD: Where? Maybe we should just use botright vertical ...
window_for_start = vim.current.window
if term.window is not None and term.window.valid:
assert term.buffer_number
window_for_start = term.window
if ( term.window.buffer.number == term.buffer_number
and int( utils.Call( 'vimspector#internal#{}term#IsFinished'.format(
api_prefix ),
term.buffer_number ) ) ):
term_options[ 'curwin' ] = 1
else:
term_options[ 'vertical' ] = 0
buffer_number = None
terminal_window = None
with utils.LetCurrentWindow( window_for_start ):
# If we're making a vertical split from the code window, make it no more
# than 80 columns and no fewer than 10. Also try and keep the code window
# at least 82 columns
if term_options[ 'vertical' ] and not term_options.get( 'curwin', 0 ):
term_options[ 'term_cols' ] = max(
min ( int( vim.eval( 'winwidth( 0 )' ) )
- settings.Int( 'code_minwidth' ),
settings.Int( 'terminal_maxwidth' ) ),
settings.Int( 'terminal_minwidth' )
)
buffer_number = int(
utils.Call(
'vimspector#internal#{}term#Start'.format( api_prefix ),
args,
term_options ) )
terminal_window = vim.current.window
if buffer_number is None or buffer_number <= 0:
# TODO: Do something better like reject the request?
raise ValueError( "Unable to start terminal" )
term.window = terminal_window
term.buffer_number = buffer_number
vim.vars[ 'vimspector_session_windows' ][ 'terminal' ] = utils.WindowID(
term.window,
vim.current.tabpage )
with utils.RestoreCursorPosition():
with utils.RestoreCurrentWindow():
with utils.RestoreCurrentBuffer( vim.current.window ):
vim.command( 'doautocmd User VimspectorTerminalOpened' )
return term