Ejemplo n.º 1
0
    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,
        }

        window_for_start = self._window
        if self._terminal_window is not None:
            assert self._terminal_buffer_number
            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))):
                window_for_start = self._terminal_window
                options['curwin'] = 1

        buffer_number = None
        terminal_window = None
        with utils.TemporaryVimOptions({
                'splitright': True,
                'equalalways': False
        }):
            with utils.LetCurrentWindow(window_for_start):
                buffer_number = int(
                    utils.Call(
                        'vimspector#internal#{}term#Start'.format(
                            self._api_prefix), args, 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")
        else:
            self._terminal_window = terminal_window
            self._terminal_buffer_number = buffer_number

        return buffer_number
Ejemplo n.º 2
0
  def _StartDebugAdapter( self ):
    self._splash_screen = utils.DisplaySplash(
      self._api_prefix,
      self._splash_screen,
      "Starting debug adapter..." )

    if self._connection:
      utils.UserMessage( 'The connection is already created. Please try again',
                         persist = True )
      return

    self._logger.info( 'Starting debug adapter with: %s',
                       json.dumps( self._adapter ) )

    self._init_complete = False
    self._on_init_complete_handlers = []
    self._launch_complete = False
    self._run_on_server_exit = None

    self._connection_type = 'job'
    if 'port' in self._adapter:
      self._connection_type = 'channel'

      if self._adapter[ 'port' ] == 'ask':
        port = utils.AskForInput( 'Enter port to connect to: ' )
        if port is None:
          self._Reset()
          return
        self._adapter[ 'port' ] = port

    self._connection_type = self._api_prefix + self._connection_type

    # TODO: Do we actually need to copy and update or does Vim do that?
    env = os.environ.copy()
    if os.name == "nt":
      env = {}
    if 'env' in self._adapter:
      env.update( self._adapter[ 'env' ] )
    self._adapter[ 'env' ] = env

    if 'cwd' not in self._adapter:
      self._adapter[ 'cwd' ] = os.getcwd()

    vim.vars[ '_vimspector_adapter_spec' ] = self._adapter
    if not vim.eval( "vimspector#internal#{}#StartDebugSession( "
                     "  g:_vimspector_adapter_spec "
                     ")".format( self._connection_type ) ):
      self._logger.error( "Unable to start debug server" )
      self._splash_screen = utils.DisplaySplash( self._api_prefix,
                                                 self._splash_screen,
                                                 "Unable to start adapter" )
    else:
      self._connection = debug_adapter_connection.DebugAdapterConnection(
        self,
        lambda msg: utils.Call(
          "vimspector#internal#{}#Send".format( self._connection_type ),
          msg ) )

    self._logger.info( 'Debug Adapter Started' )
Ejemplo n.º 3
0
def DefineSign(name, text, texthl, col='right', **kwargs):
    if col == 'right':
        if int(utils.Call('strdisplaywidth', text)) < 2:
            text = ' ' + text

    text = text.replace(' ', r'\ ')

    cmd = f'sign define { name } text={ text } texthl={ texthl }'
    for key, value in kwargs.items():
        cmd += f' { key }={ value }'

    vim.command(cmd)
Ejemplo n.º 4
0
def DefineSign(name, text, double_text, texthl, col='right', **kwargs):
    if utils.GetVimValue(vim.options, 'ambiwidth', '') == 'double':
        text = double_text

    if col == 'right':
        if int(utils.Call('strdisplaywidth', text)) < 2:
            text = ' ' + text

    text = text.replace(' ', r'\ ')

    cmd = f'sign define { name } text={ text } texthl={ texthl }'
    for key, value in kwargs.items():
        cmd += f' { key }={ value }'

    vim.command(cmd)
Ejemplo n.º 5
0
  def OnRequest_runInTerminal( self, message ):
    params = message[ 'arguments' ]

    if not params.get( 'cwd' ) :
      params[ 'cwd' ] = self._workspace_root
      self._logger.debug( 'Defaulting working directory to %s',
                          params[ 'cwd' ] )

    term_id = self._codeView.LaunchTerminal( params )

    response = {
      'processId': int( utils.Call(
        'vimspector#internal#{}term#GetPID'.format( self._api_prefix ),
        term_id ) )
    }

    self._connection.DoResponse( message, None, response )
Ejemplo n.º 6
0
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
Ejemplo n.º 7
0
    def _StartDebugAdapter(self):
        self._splash_screen = utils.DisplaySplash(self._api_prefix,
                                                  self._splash_screen,
                                                  "Starting debug adapter...")

        if self._connection:
            utils.UserMessage(
                'The connection is already created. Please try again',
                persist=True)
            return

        # There is the problem with the current flow when we try to use a debugger
        # which is located fully on the remote server e.g container or SSH Server.
        # The problem is in the order: it tries to connect to debugger before it is even started
        # To solve that problem, I offer adding an optional boolean key "bootstrap" to a configuration.
        # If we have that key, we should perform launch or attach commands to first bootstrap a remote debugger.
        # Then we can skip that step in the _Launch() function
        if self._adapter.get('bootstrap'):
            self._BootstrapRemoteDebugger()

        self._logger.info('Starting debug adapter with: %s',
                          json.dumps(self._adapter))

        self._init_complete = False
        self._on_init_complete_handlers = []
        self._launch_complete = False
        self._run_on_server_exit = None

        self._connection_type = 'job'
        if 'port' in self._adapter:
            self._connection_type = 'channel'

            if self._adapter['port'] == 'ask':
                port = utils.AskForInput('Enter port to connect to: ')
                if port is None:
                    self._Reset()
                    return
                self._adapter['port'] = port

        self._connection_type = self._api_prefix + self._connection_type

        # TODO: Do we actually need to copy and update or does Vim do that?
        env = os.environ.copy()
        if 'env' in self._adapter:
            env.update(self._adapter['env'])
        self._adapter['env'] = env

        if 'cwd' not in self._adapter:
            self._adapter['cwd'] = os.getcwd()

        vim.vars['_vimspector_adapter_spec'] = self._adapter
        if not vim.eval("vimspector#internal#{}#StartDebugSession( "
                        "  g:_vimspector_adapter_spec "
                        ")".format(self._connection_type)):
            self._logger.error("Unable to start debug server")
            self._splash_screen = utils.DisplaySplash(
                self._api_prefix, self._splash_screen,
                "Unable to start adapter")
        else:
            self._connection = debug_adapter_connection.DebugAdapterConnection(
                self, lambda msg: utils.Call(
                    "vimspector#internal#{}#Send".format(self._connection_type
                                                         ), msg))

        self._logger.info('Debug Adapter Started')
Ejemplo n.º 8
0
  def _StartDebugAdapter( self ):
    self._splash_screen = utils.DisplaySplash(
      self._api_prefix,
      self._splash_screen,
      "Starting debug adapter..." )

    if self._connection:
      utils.UserMessage( 'The connection is already created. Please try again',
                         persist = True )
      return

    self._logger.info( 'Starting debug adapter with: %s',
                       json.dumps( self._adapter ) )

    self._init_complete = False
    self._launch_complete = False
    self._run_on_server_exit = None

    self._connection_type = 'job'
    if 'port' in self._adapter:
      self._connection_type = 'channel'

      if self._adapter[ 'port' ] == 'ask':
        port = utils.AskForInput( 'Enter port to connect to: ' )
        if port is None:
          self._Reset()
          return
        self._adapter[ 'port' ] = port

    self._connection_type = self._api_prefix + self._connection_type
    self._logger.debug( f"Connection Type: { self._connection_type }" )

    self._adapter[ 'env' ] = self._adapter.get( 'env', {} )

    if 'cwd' not in self._adapter:
      self._adapter[ 'cwd' ] = os.getcwd()

    vim.vars[ '_vimspector_adapter_spec' ] = self._adapter
    if not vim.eval( "vimspector#internal#{}#StartDebugSession( "
                     "  g:_vimspector_adapter_spec "
                     ")".format( self._connection_type ) ):
      self._logger.error( "Unable to start debug server" )
      self._splash_screen = utils.DisplaySplash( self._api_prefix,
                                                 self._splash_screen,
                                                 "Unable to start adapter" )
    else:
      if 'custom_handler' in self._adapter:
        spec = self._adapter[ 'custom_handler' ]
        if isinstance( spec, dict ):
          module = spec[ 'module' ]
          cls = spec[ 'class' ]
        else:
          module, cls = spec.rsplit( '.', 1 )

        CustomHandler = getattr( importlib.import_module( module ), cls )
        handlers = [ CustomHandler( self ), self ]
      else:
        handlers = [ self ]

      self._connection = debug_adapter_connection.DebugAdapterConnection(
        handlers,
        lambda msg: utils.Call(
          "vimspector#internal#{}#Send".format( self._connection_type ),
          msg ) )

    self._logger.info( 'Debug Adapter Started' )
Ejemplo n.º 9
0
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