def LaunchTerminal( self, params ): # kind = params.get( 'kind', 'integrated' ) # FIXME: We don't support external terminals, and only open in the # integrated one. cwd = params[ 'cwd' ] args = params[ 'args' ] env = params.get( 'env', {} ) options = { 'vertical': 1, 'norestore': 1, 'cwd': cwd, 'env': env, } buffer_number = None with utils.TemporaryVimOptions( { 'splitright': True, 'equalalways': False } ): with utils.RestoreCurrentWindow(): vim.current.window = self._window # TODO/FIXME: Do something about closing this when we reset ? vim_cmd = 'term_start( {}, {} )'.format( json.dumps( args ), json.dumps( options ) ) self._logger.debug( 'Start terminal: {}'.format( vim_cmd ) ) buffer_number = int( vim.eval( vim_cmd ) ) if buffer_number is None or buffer_number <= 0: # TODO: Do something better like reject the request? raise ValueError( "Unable to start terminal" ) return buffer_number
def _CreateBuffer(self, category, file_name=None, cmd=None, completion_handler=None, syntax=None): buf_to_delete = None if (not self._buffers and self._window is not None and self._window.valid and not self._window.buffer.name): # If there's an empty buffer in the current window that we're not using, # delete it. We could try and use it, but that complicates the call to # SetUpCommandBuffer buf_to_delete = self._window.buffer if file_name is not None: assert cmd is None if install.GetOS() == "windows": # FIXME: Can't display fiels in windows (yet?) return cmd = ['tail', '-F', '-n', '+1', '--', file_name] if cmd is not None: out = utils.SetUpCommandBuffer( cmd, category, self._api_prefix, completion_handler=completion_handler) self._buffers[category] = TabBuffer(out, len(self._buffers)) self._buffers[category].is_job = True self._RenderWinBar(category) else: if category == 'Console': name = 'vimspector.Console' else: name = 'vimspector.Output:{0}'.format(category) tab_buffer = TabBuffer(utils.NewEmptyBuffer(), len(self._buffers)) self._buffers[category] = tab_buffer if category == 'Console': utils.SetUpPromptBuffer(tab_buffer.buf, name, '> ', 'vimspector#EvaluateConsole', 'vimspector#OmniFuncConsole') else: utils.SetUpHiddenBuffer(tab_buffer.buf, name) self._RenderWinBar(category) self._buffers[category].syntax = utils.SetSyntax( self._buffers[category].syntax, syntax, self._buffers[category].buf) if buf_to_delete: with utils.RestoreCurrentWindow(): self._ShowOutput(category) utils.CleanUpHiddenBuffer(buf_to_delete)
def _SetUpUI( self ): vim.command( 'tab split' ) self._uiTab = vim.current.tabpage # Code window code_window = vim.current.window self._codeView = code.CodeView( code_window, self._api_prefix ) # Call stack vim.command( f'topleft vertical { settings.Int( "sidebar_width", 50 ) }new' ) stack_trace_window = vim.current.window one_third = int( vim.eval( 'winheight( 0 )' ) ) / 3 self._stackTraceView = stack_trace.StackTraceView( self, self._connection, stack_trace_window ) # Watches vim.command( 'leftabove new' ) watch_window = vim.current.window # Variables vim.command( 'leftabove new' ) vars_window = vim.current.window with utils.LetCurrentWindow( vars_window ): vim.command( f'{ one_third }wincmd _' ) with utils.LetCurrentWindow( watch_window ): vim.command( f'{ one_third }wincmd _' ) with utils.LetCurrentWindow( stack_trace_window ): vim.command( f'{ one_third }wincmd _' ) self._variablesView = variables.VariablesView( self._connection, vars_window, watch_window ) # Output/logging vim.current.window = code_window vim.command( f'rightbelow { settings.Int( "bottombar_height", 10 ) }new' ) output_window = vim.current.window self._outputView = output.OutputView( self._connection, output_window, self._api_prefix ) # TODO: If/when we support multiple sessions, we'll need some way to # indicate which tab was created and store all the tabs vim.vars[ 'vimspector_session_windows' ] = { 'tabpage': self._uiTab.number, 'code': utils.WindowID( code_window, self._uiTab ), 'stack_trace': utils.WindowID( stack_trace_window, self._uiTab ), 'variables': utils.WindowID( vars_window, self._uiTab ), 'watches': utils.WindowID( watch_window, self._uiTab ), 'output': utils.WindowID( output_window, self._uiTab ), } with utils.RestoreCursorPosition(): with utils.RestoreCurrentWindow(): with utils.RestoreCurrentBuffer( vim.current.window ): vim.command( 'doautocmd User VimspectorUICreated' )
def _SetUpUIVertical( self ): # Code window code_window = vim.current.window self._codeView = code.CodeView( code_window, self._api_prefix ) # Call stack vim.command( f'topleft { settings.Int( "topbar_height" ) }new' ) stack_trace_window = vim.current.window one_third = int( vim.eval( 'winwidth( 0 )' ) ) / 3 self._stackTraceView = stack_trace.StackTraceView( self, stack_trace_window ) # Watches vim.command( 'leftabove vertical new' ) watch_window = vim.current.window # Variables vim.command( 'leftabove vertical new' ) vars_window = vim.current.window with utils.LetCurrentWindow( vars_window ): vim.command( f'{ one_third }wincmd |' ) with utils.LetCurrentWindow( watch_window ): vim.command( f'{ one_third }wincmd |' ) with utils.LetCurrentWindow( stack_trace_window ): vim.command( f'{ one_third }wincmd |' ) self._variablesView = variables.VariablesView( vars_window, watch_window ) # Output/logging vim.current.window = code_window vim.command( f'rightbelow { settings.Int( "bottombar_height" ) }new' ) output_window = vim.current.window self._outputView = output.DAPOutputView( output_window, self._api_prefix ) # TODO: If/when we support multiple sessions, we'll need some way to # indicate which tab was created and store all the tabs vim.vars[ 'vimspector_session_windows' ] = { 'mode': 'vertical', 'tabpage': self._uiTab.number, 'code': utils.WindowID( code_window, self._uiTab ), 'stack_trace': utils.WindowID( stack_trace_window, self._uiTab ), 'variables': utils.WindowID( vars_window, self._uiTab ), 'watches': utils.WindowID( watch_window, self._uiTab ), 'output': utils.WindowID( output_window, self._uiTab ), 'eval': None # this is going to be updated every time eval popup is opened } with utils.RestoreCursorPosition(): with utils.RestoreCurrentWindow(): with utils.RestoreCurrentBuffer( vim.current.window ): vim.command( 'doautocmd User VimspectorUICreated' )
def RunInstaller( api_prefix, leave_open, *args, **kwargs ): from vimspector import utils, output, settings import vim if not args: args = settings.List( 'install_gadgets' ) if not args: return args = GadgetListToInstallerArgs( *args ) vimspector_home = utils.GetVimValue( vim.vars, 'vimspector_home' ) vimspector_base_dir = utils.GetVimspectorBase() global OUTPUT_VIEW _ResetInstaller() with utils.RestoreCurrentWindow(): vim.command( f'botright { settings.Int( "bottombar_height" ) }new' ) win = vim.current.window OUTPUT_VIEW = output.OutputView( win, api_prefix ) cmd = [ PathToAnyWorkingPython3(), '-u', os.path.join( vimspector_home, 'install_gadget.py' ), '--quiet', '--update-gadget-config', ] if not vimspector_base_dir == vimspector_home: cmd.extend( [ '--basedir', vimspector_base_dir ] ) cmd.extend( args ) def handler( exit_code ): if exit_code == 0: if not leave_open: _ResetInstaller() utils.UserMessage( "Vimspector gadget installation complete!" ) vim.command( 'silent doautocmd User VimspectorInstallSuccess' ) if 'then' in kwargs: kwargs[ 'then' ]() else: utils.UserMessage( 'Vimspector gadget installation reported errors', error = True ) vim.command( 'silent doautocmd User VimspectorInstallFailed' ) OUTPUT_VIEW.RunJobWithOutput( 'Installer', cmd, completion_handler = handler, syntax = 'vimspector-installer' ) OUTPUT_VIEW.ShowOutput( 'Installer' )
def OnOutput(self, event): category = CategoryToBuffer(event.get('category') or 'output') if category not in self._buffers: self._CreateBuffer(category) buf = self._buffers[category] with utils.ModifiableScratchBuffer(buf): utils.AppendToBuffer(buf, event['output'].splitlines()) # Scroll the buffer with utils.RestoreCurrentWindow(): with utils.RestoreCurrentBuffer(self._window): self.ShowOutput(category) vim.command('normal G')
def _Print(self, category, text_lines): if category not in self._buffers: self._CreateBuffer(category) buf = self._buffers[category].buf with utils.ModifiableScratchBuffer(buf): utils.AppendToBuffer(buf, text_lines) self._ToggleFlag(category, True) # Scroll the buffer with utils.RestoreCurrentWindow(): with utils.RestoreCurrentBuffer(self._window): self._ShowOutput(category)
def _CreateBuffer(self, category): with utils.RestoreCurrentWindow(): vim.current.window = self._window with utils.RestoreCurrentBuffer(self._window): vim.command('enew') self._buffers[category] = vim.current.buffer if category == 'Console': utils.SetUpPromptBuffer(self._buffers[category], 'vimspector.Console', '> ', 'vimspector#EvaluateConsole', hidden=True) else: utils.SetUpHiddenBuffer( self._buffers[category], 'vimspector.Output:{0}'.format(category)) vim.command("nnoremenu WinBar.{0} " ":call vimspector#ShowOutput( '{0}' )<CR>".format( utils.Escape(category)))
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: assert cmd is None cmd = ['tail', '-F', '-n', '+1', '--', file_name] if cmd is not None: out, err = utils.SetUpCommandBuffer(cmd, category) self._buffers[category + '-out'] = TabBuffer( out, len(self._buffers)) self._buffers[category + '-out'].is_job = True self._buffers[category + '-err'] = TabBuffer( err, len(self._buffers)) self._buffers[category + '-err'].is_job = False self._RenderWinBar(category + '-out') self._RenderWinBar(category + '-err') else: vim.command('enew') tab_buffer = TabBuffer(vim.current.buffer, len(self._buffers)) self._buffers[category] = tab_buffer if category == 'Console': utils.SetUpPromptBuffer(tab_buffer.buf, 'vimspector.Console', '> ', 'vimspector#EvaluateConsole', hidden=True) else: utils.SetUpHiddenBuffer( tab_buffer.buf, 'vimspector.Output:{0}'.format(category)) self._RenderWinBar(category)
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
def _ToggleFlag(self, category, flag): if self._buffers[category].flag != flag: self._buffers[category].flag = flag with utils.RestoreCurrentWindow(): vim.current.window = self._window self._RenderWinBar(category)
def LaunchTerminal(api_prefix, params, window_for_start, existing_term): if not existing_term: term = Terminal() else: term = existing_term cwd = params['cwd'] or os.getcwd() args = params['args'] or [] env = params.get('env') or {} term_options = { 'norestore': 1, 'cwd': cwd, 'env': env, } if settings.Get('ui_mode') == 'horizontal': # force-horizontal term_options['vertical'] = 1 elif utils.GetVimValue(vim.vars['vimspector_session_windows'], 'mode') == 'horizontal': # horizontal, which means that we should have enough space for: # - sidebar # - code min # - term min width # - + 2 vertical spaders # - + 3 columns for signs term_options['vertical'] = 1 # if we don't have enough space for terminal_maxwidth, then see if we have # enough vertically for terminal_maxheight, in which case, # that seems a better fit term_horiz_max = (settings.Int('sidebar_width') + 1 + 2 + 3 + settings.Int('code_minwidth') + 1 + settings.Int('terminal_maxwidth')) term_vert_max = (settings.Int('bottombar_height') + 1 + settings.Int('code_minheight') + 1 + settings.Int('terminal_minheight')) if (vim.options['columns'] < term_horiz_max and vim.options['lines'] >= term_vert_max): # Looks like it, let's try that layout term_options['vertical'] = 0 else: # vertical - we need enough space horizontally for the code+terminal, but we # may fit better with code above terminal term_options['vertical'] = 0 term_horiz_max = (settings.Int('code_minwidth') + 3 + settings.Int('terminal_maxwidth') + 1) if vim.options['columns'] > term_horiz_max: term_options['vertical'] = 1 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.get('curwin', 0): pass elif term_options['vertical']: term_options['term_cols'] = max( min( int(vim.eval('winwidth( 0 )')) - settings.Int('code_minwidth'), settings.Int('terminal_maxwidth')), settings.Int('terminal_minwidth')) else: term_options['term_rows'] = max( min( int(vim.eval('winheight( 0 )')) - settings.Int('code_minheight'), settings.Int('terminal_maxheight')), settings.Int('terminal_minheight')) 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 utils.UpdateSessionWindows( {'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