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' )")))
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 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)))
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')
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)
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')
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)))
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)
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
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')
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
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
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)
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
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' )")))
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
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' )")))
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