Example #1
0
    def __init__(self, variables_win, watches_win):
        self._logger = logging.getLogger(__name__)
        utils.SetUpLogging(self._logger)

        self._connection = None
        self._current_syntax = ''

        # Set up the "Variables" buffer in the variables_win
        self._scopes: typing.List[Scope] = []
        self._vars = View(variables_win, {}, self._DrawScopes)
        utils.SetUpHiddenBuffer(self._vars.buf, 'vimspector.Variables')
        with utils.LetCurrentWindow(variables_win):
            vim.command(
                'nnoremap <buffer> <CR> :call vimspector#ExpandVariable()<CR>')

        # Set up the "Watches" buffer in the watches_win (and create a WinBar in
        # there)
        self._watches: typing.List[Watch] = []
        self._watch = View(watches_win, {}, self._DrawWatches)
        utils.SetUpPromptBuffer(self._watch.buf, 'vimspector.Watches',
                                'Expression: ', 'vimspector#AddWatchPrompt',
                                'vimspector#OmniFuncWatch')
        with utils.LetCurrentWindow(watches_win):
            vim.command(
                'nnoremap <buffer> <CR> :call vimspector#ExpandVariable()<CR>')
            vim.command(
                'nnoremap <buffer> <DEL> :call vimspector#DeleteWatch()<CR>')

            vim.command('nnoremenu 1.1 WinBar.New '
                        ':call vimspector#AddWatch()<CR>')
            vim.command('nnoremenu 1.2 WinBar.Expand/Collapse '
                        ':call vimspector#ExpandVariable()<CR>')
            vim.command('nnoremenu 1.3 WinBar.Delete '
                        ':call vimspector#DeleteWatch()<CR>')

        # Set the (global!) balloon expr if supported
        has_balloon = int(vim.eval("has( 'balloon_eval' )"))
        has_balloon_term = int(vim.eval("has( 'balloon_eval_term' )"))

        self._oldoptions = {}
        if has_balloon or has_balloon_term:
            self._oldoptions = {
                'balloonexpr': vim.options['balloonexpr'],
                'balloondelay': vim.options['balloondelay'],
            }
            vim.options[
                'balloonexpr'] = 'vimspector#internal#balloon#BalloonExpr()'
            vim.options['balloondelay'] = 250

        if has_balloon:
            self._oldoptions['ballooneval'] = vim.options['ballooneval']
            vim.options['ballooneval'] = True

        if has_balloon_term:
            self._oldoptions['balloonevalterm'] = vim.options[
                'balloonevalterm']
            vim.options['balloonevalterm'] = True

        self._is_term = not bool(int(vim.eval("has( 'gui_running' )")))
Example #2
0
  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' )
Example #4
0
    def SetSyntax(self, syntax):
        if not syntax:
            syntax = ''

        if self._current_syntax == syntax:
            return

        self._current_syntax = syntax

        with utils.LetCurrentWindow(self._vars.win):
            vim.command('set syntax={}'.format(utils.Escape(syntax)))

        with utils.LetCurrentWindow(self._watch.win):
            vim.command('set syntax={}'.format(utils.Escape(syntax)))
Example #5
0
    def __init__(self, window, api_prefix):
        self._window = window
        self._api_prefix = api_prefix

        self._terminal_window = None
        self._terminal_buffer_number = None
        self.current_syntax = None

        self._logger = logging.getLogger(__name__)
        utils.SetUpLogging(self._logger)

        self._next_sign_id = 1
        self._breakpoints = defaultdict(list)
        self._signs = {'vimspectorPC': None, 'breakpoints': []}

        with utils.LetCurrentWindow(self._window):
            vim.command(
                'nnoremenu WinBar.Continue :call vimspector#Continue()<CR>')
            vim.command(
                'nnoremenu WinBar.Next :call vimspector#StepOver()<CR>')
            vim.command(
                'nnoremenu WinBar.Step :call vimspector#StepInto()<CR>')
            vim.command(
                'nnoremenu WinBar.Finish :call vimspector#StepOut()<CR>')
            vim.command('nnoremenu WinBar.Pause :call vimspector#Pause()<CR>')
            vim.command('nnoremenu WinBar.Stop :call vimspector#Stop()<CR>')
            vim.command(
                'nnoremenu WinBar.Restart :call vimspector#Restart()<CR>')
            vim.command('nnoremenu WinBar.Reset :call vimspector#Reset()<CR>')

            if not utils.SignDefined('vimspectorPC'):
                vim.command('sign define vimspectorPC text=-> texthl=Search')
Example #6
0
    def _ToggleFlag(self, category, flag):
        if self._buffers[category].flag != flag:
            self._buffers[category].flag = flag

            if self._window.valid:
                with utils.LetCurrentWindow(self._window):
                    self._RenderWinBar(category)
Example #7
0
    def __init__(self, window, api_prefix):
        self._window = window
        self._api_prefix = api_prefix

        self._terminal_window = None
        self._terminal_buffer_number = None
        self.current_syntax = None

        self._logger = logging.getLogger(__name__)
        utils.SetUpLogging(self._logger)

        self._next_sign_id = 1
        self._breakpoints = defaultdict(list)
        self._signs = {'vimspectorPC': None, 'breakpoints': []}

        with utils.LetCurrentWindow(self._window):
            vim.command(
                'nnoremenu WinBar.■\\ Stop :call vimspector#Stop()<CR>')
            vim.command(
                'nnoremenu WinBar.▶\\ Cont :call vimspector#Continue()<CR>')
            vim.command(
                'nnoremenu WinBar.▷\\ Pause :call vimspector#Pause()<CR>')
            vim.command(
                'nnoremenu WinBar.↷\\ Next :call vimspector#StepOver()<CR>')
            vim.command(
                'nnoremenu WinBar.→\\ Step :call vimspector#StepInto()<CR>')
            vim.command(
                'nnoremenu WinBar.←\\ Out :call vimspector#StepOut()<CR>')
            vim.command('nnoremenu WinBar.⟲: :call vimspector#Restart()<CR>')
            vim.command('nnoremenu WinBar.✕ :call vimspector#Reset()<CR>')

            if not utils.SignDefined('vimspectorPC'):
                utils.DefineSign('vimspectorPC', text='▶', texthl='MatchParen')
Example #8
0
    def _RenderWinBar(self, category):
        if not utils.UseWinBar():
            return

        if not self._window.valid:
            return

        with utils.LetCurrentWindow(self._window):
            tab_buffer = self._buffers[category]

            try:
                if tab_buffer.flag:
                    vim.command('nunmenu WinBar.{}'.format(
                        utils.Escape(category)))
                else:
                    vim.command('nunmenu WinBar.{}*'.format(
                        utils.Escape(category)))
            except vim.error as e:
                # E329 means the menu doesn't exist; ignore that.
                if 'E329' not in str(e):
                    raise

            vim.command(
                "nnoremenu <silent> 1.{0} WinBar.{1}{2} "
                ":call vimspector#ShowOutputInWindow( {3}, '{1}' )<CR>".format(
                    tab_buffer.index,
                    utils.Escape(category), '*' if tab_buffer.flag else '',
                    utils.WindowID(self._window)))
Example #9
0
    def _CreateBuffer(self, category, file_name=None, cmd=None):
        with utils.LetCurrentWindow(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)
Example #10
0
    def __init__(self, session, win):
        self._logger = logging.getLogger(__name__)
        utils.SetUpLogging(self._logger)

        self._buf = win.buffer
        self._session = session
        self._connection = None

        self._current_thread = None
        self._current_frame = None
        self._current_syntax = ""

        self._threads = []
        self._sources = {}
        self._scratch_buffers = []

        # FIXME: This ID is by group, so should be module scope
        self._next_sign_id = 1

        utils.SetUpHiddenBuffer(self._buf, 'vimspector.StackTrace')
        utils.SetUpUIWindow(win)

        mappings = settings.Dict('mappings')['stack_trace']

        with utils.LetCurrentWindow(win):
            for mapping in utils.GetVimList(mappings, 'expand_or_jump'):
                vim.command(f'nnoremap <silent> <buffer> { mapping } '
                            ':<C-U>call vimspector#GoToFrame()<CR>')

            for mapping in utils.GetVimList(mappings, 'focus_thread'):
                vim.command(f'nnoremap <silent> <buffer> { mapping } '
                            ':<C-U>call vimspector#SetCurrentThread()<CR>')

            if utils.UseWinBar():
                vim.command('nnoremenu <silent> 1.1 WinBar.Pause/Continue '
                            ':call vimspector#PauseContinueThread()<CR>')
                vim.command('nnoremenu <silent> 1.2 WinBar.Expand/Collapse '
                            ':call vimspector#GoToFrame()<CR>')
                vim.command('nnoremenu <silent> 1.3 WinBar.Focus '
                            ':call vimspector#SetCurrentThread()<CR>')

        win.options['cursorline'] = False

        if not signs.SignDefined('vimspectorCurrentThread'):
            signs.DefineSign('vimspectorCurrentThread',
                             text='▶ ',
                             double_text='▶',
                             texthl='MatchParen',
                             linehl='CursorLine')

        self._line_to_frame = {}
        self._line_to_thread = {}

        self._requesting_threads = StackTraceView.ThreadRequestState.NO
        self._pending_thread_request = None
Example #11
0
    def __init__(self, window, api_prefix, render_event_emitter,
                 IsBreakpointPresentAt):

        self._window = window
        self._api_prefix = api_prefix
        self._render_subject = render_event_emitter.subscribe(self._DisplayPC)
        self._IsBreakpointPresentAt = IsBreakpointPresentAt

        self._terminal = None
        self.current_syntax = None

        self._logger = logging.getLogger(__name__)
        utils.SetUpLogging(self._logger)

        # FIXME: This ID is by group, so should be module scope
        self._next_sign_id = 1
        self._signs = {
            'vimspectorPC': None,
        }
        self._current_frame = None
        self._scratch_buffers = []

        with utils.LetCurrentWindow(self._window):
            if utils.UseWinBar():
                # Buggy neovim doesn't render correctly when the WinBar is defined:
                # https://github.com/neovim/neovim/issues/12689
                vim.command('nnoremenu WinBar.■\\ Stop '
                            ':call vimspector#Stop()<CR>')
                vim.command('nnoremenu WinBar.▶\\ Cont '
                            ':call vimspector#Continue()<CR>')
                vim.command('nnoremenu WinBar.▷\\ Pause '
                            ':call vimspector#Pause()<CR>')
                vim.command('nnoremenu WinBar.↷\\ Next '
                            ':call vimspector#StepOver()<CR>')
                vim.command('nnoremenu WinBar.→\\ Step '
                            ':call vimspector#StepInto()<CR>')
                vim.command('nnoremenu WinBar.←\\ Out '
                            ':call vimspector#StepOut()<CR>')
                vim.command('nnoremenu WinBar.⟲: '
                            ':call vimspector#Restart()<CR>')
                vim.command('nnoremenu WinBar.✕ '
                            ':call vimspector#Reset()<CR>')

            if not signs.SignDefined('vimspectorPC'):
                signs.DefineSign('vimspectorPC',
                                 text='▶',
                                 double_text='▶',
                                 texthl='MatchParen',
                                 linehl='CursorLine')
            if not signs.SignDefined('vimspectorPCBP'):
                signs.DefineSign('vimspectorPCBP',
                                 text='●▶',
                                 double_text='▷',
                                 texthl='MatchParen',
                                 linehl='CursorLine')
Example #12
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
Example #13
0
    def _RenderWinBar(self, category):
        if not self._window.valid:
            return

        with utils.LetCurrentWindow(self._window):
            tab_buffer = self._buffers[category]

            try:
                if tab_buffer.flag:
                    vim.command('nunmenu WinBar.{}'.format(
                        utils.Escape(category)))
                else:
                    vim.command('nunmenu WinBar.{}*'.format(
                        utils.Escape(category)))
            except vim.error as e:
                # E329 means the menu doesn't exist; ignore that.
                if 'E329' not in str(e):
                    raise
Example #14
0
    def _CreateBuffer(self, category, file_name=None, cmd=None):
        win = self._window
        if not win.valid:
            # We need to borrow the current window
            win = vim.current.window

        with utils.LetCurrentWindow(win):
            with utils.RestoreCurrentBuffer(win):

                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, err = utils.SetUpCommandBuffer(
                        cmd, category, self._api_prefix)
                    self._buffers[category + '-out'] = TabBuffer(
                        out, len(self._buffers))
                    self._buffers[category + '-out'].is_job = True
                    self._buffers[category + '-out'].job_category = category
                    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')
                    else:
                        utils.SetUpHiddenBuffer(
                            tab_buffer.buf,
                            'vimspector.Output:{0}'.format(category))

                    self._RenderWinBar(category)
Example #15
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,
        }

        buffer_number = None
        with utils.TemporaryVimOptions({
                'splitright': True,
                'equalalways': False
        }):
            with utils.LetCurrentWindow(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
Example #16
0
    def __init__(self, connection, variables_win, watches_win):
        self._logger = logging.getLogger(__name__)
        utils.SetUpLogging(self._logger)

        self._vars = View(variables_win, {}, self._DrawScopes)
        self._watch = View(watches_win, {}, self._DrawWatches)
        self._connection = connection
        self._current_syntax = ''

        # Allows us to hit <CR> to expand/collapse variables
        with utils.LetCurrentWindow(self._vars.win):
            vim.command(
                'nnoremap <buffer> <CR> :call vimspector#ExpandVariable()<CR>')

        # This is actually the tree (scopes are alwyas the root)
        #  it's just a list of DAP scope dicts, with one magic key (_variables)
        #  _variables is a list of DAP variable with the same magic key
        #
        # If _variables is present, then we have requested and should display the
        # children. Otherwise, we haven't or shouldn't.
        self._scopes = []

        # This is similar to scopes, but the top level is an "expression" (request)
        # containing a special '_result' key which is the response. The response
        # structure con contain _variables and is handled identically to the scopes
        # above. It also has a special _line key which is where we printed it (last)
        self._watches = []

        # Allows us to hit <CR> to expand/collapse variables
        with utils.LetCurrentWindow(self._watch.win):
            vim.command(
                'nnoremap <buffer> <CR> :call vimspector#ExpandVariable()<CR>')
            vim.command(
                'nnoremap <buffer> <DEL> :call vimspector#DeleteWatch()<CR>')

        utils.SetUpScratchBuffer(self._vars.win.buffer, 'vimspector.Variables')
        utils.SetUpPromptBuffer(self._watch.win.buffer, 'vimspector.Watches',
                                'Expression: ', 'vimspector#AddWatchPrompt')

        has_balloon = int(vim.eval("has( 'balloon_eval' )"))
        has_balloon_term = int(vim.eval("has( 'balloon_eval_term' )"))

        self._oldoptions = {}
        if has_balloon or has_balloon_term:
            self._oldoptions = {
                'balloonexpr': vim.options['balloonexpr'],
                'balloondelay': vim.options['balloondelay'],
            }
            vim.options[
                'balloonexpr'] = 'vimspector#internal#balloon#BalloonExpr()'
            vim.options['balloondelay'] = 250

        if has_balloon:
            self._oldoptions['ballooneval'] = vim.options['ballooneval']
            vim.options['ballooneval'] = True

        if has_balloon_term:
            self._oldoptions['balloonevalterm'] = vim.options[
                'balloonevalterm']
            vim.options['balloonevalterm'] = True

        self._is_term = not bool(int(vim.eval("has( 'gui_running' )")))
Example #17
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
Example #18
0
    def __init__(self, variables_win, watches_win):
        self._logger = logging.getLogger(__name__)
        utils.SetUpLogging(self._logger)

        self._connection = None
        self._current_syntax = ''
        self._server_capabilities = None

        self._variable_eval: Scope = None
        self._variable_eval_view: View = None

        mappings = settings.Dict('mappings')['variables']

        # Set up the "Variables" buffer in the variables_win
        self._scopes: typing.List[Scope] = []
        self._vars = View(variables_win, {}, self._DrawScopes)
        utils.SetUpHiddenBuffer(self._vars.buf, 'vimspector.Variables')
        with utils.LetCurrentWindow(variables_win):
            if utils.UseWinBar():
                vim.command('nnoremenu <silent> 1.1 WinBar.Set '
                            ':call vimspector#SetVariableValue()<CR>')
            AddExpandMappings(mappings)

        # Set up the "Watches" buffer in the watches_win (and create a WinBar in
        # there)
        self._watches: typing.List[Watch] = []
        self._watch = View(watches_win, {}, self._DrawWatches)
        utils.SetUpPromptBuffer(self._watch.buf, 'vimspector.Watches',
                                'Expression: ', 'vimspector#AddWatchPrompt',
                                'vimspector#OmniFuncWatch')
        with utils.LetCurrentWindow(watches_win):
            AddExpandMappings(mappings)
            for mapping in utils.GetVimList(mappings, 'delete'):
                vim.command(
                    f'nnoremap <buffer> { mapping } :call vimspector#DeleteWatch()<CR>'
                )

            if utils.UseWinBar():
                vim.command('nnoremenu <silent> 1.1 WinBar.New '
                            ':call vimspector#AddWatch()<CR>')
                vim.command('nnoremenu <silent> 1.2 WinBar.Expand/Collapse '
                            ':call vimspector#ExpandVariable()<CR>')
                vim.command('nnoremenu <silent> 1.3 WinBar.Delete '
                            ':call vimspector#DeleteWatch()<CR>')
                vim.command('nnoremenu <silent> 1.1 WinBar.Set '
                            ':call vimspector#SetVariableValue()<CR>')

        # Set the (global!) balloon expr if supported
        has_balloon = int(vim.eval("has( 'balloon_eval' )"))
        has_balloon_term = int(vim.eval("has( 'balloon_eval_term' )"))

        self._oldoptions = {}
        if has_balloon or has_balloon_term:
            self._oldoptions = {
                'balloonexpr': vim.options['balloonexpr'],
                'balloondelay': vim.options['balloondelay'],
            }
            vim.options['balloonexpr'] = ("vimspector#internal#"
                                          "balloon#HoverTooltip()")

            vim.options['balloondelay'] = 250

        if has_balloon:
            self._oldoptions['ballooneval'] = vim.options['ballooneval']
            vim.options['ballooneval'] = True

        if has_balloon_term:
            self._oldoptions['balloonevalterm'] = vim.options[
                'balloonevalterm']
            vim.options['balloonevalterm'] = True

        self._is_term = not bool(int(vim.eval("has( 'gui_running' )")))
Example #19
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