def _DisplayPC( self ): frame = self._current_frame if not frame: return self._UndisplayPC( clear_pc = False ) # FIXME: Do we relly need to keep using up IDs ? self._signs[ 'vimspectorPC' ] = self._next_sign_id self._next_sign_id += 1 sign = 'vimspectorPC' # If there's also a breakpoint on this line, use vimspectorPCBP for bp in self._breakpoints.get( frame[ 'source' ][ 'path' ], [] ): if 'line' not in bp: continue if bp[ 'line' ] == frame[ 'line' ]: sign = 'vimspectorPCBP' break if utils.BufferExists( frame[ 'source' ][ 'path' ] ): signs.PlaceSign( self._signs[ 'vimspectorPC' ], 'VimspectorCode', sign, frame[ 'source' ][ 'path' ], frame[ 'line' ] )
def _DrawThreads( self ): self._line_to_frame.clear() self._line_to_thread.clear() if self._current_thread_sign_id: signs.UnplaceSign( self._current_thread_sign_id, 'VimspectorStackTrace' ) else: self._current_thread_sign_id = 1 with utils.ModifiableScratchBuffer( self._buf ): with utils.RestoreCursorPosition(): utils.ClearBuffer( self._buf ) for thread in self._threads: icon = '+' if not thread.IsExpanded() else '-' line = utils.AppendToBuffer( self._buf, f'{icon} Thread {thread.id}: {thread.thread["name"]} ' f'({thread.State()})' ) if self._current_thread == thread.id: # TODO - Scroll the window such that this line is visible (e.g. at # the top) signs.PlaceSign( self._current_thread_sign_id, 'VimspectorStackTrace', 'vimspectorCurrentThread', self._buf.name, line ) self._line_to_thread[ line ] = thread self._DrawStackTrace( thread )
def _ShowBreakpoints( self ): for file_name, line_breakpoints in self._line_breakpoints.items(): for bp in line_breakpoints: self._SignToLine( file_name, bp ) if 'sign_id' in bp: signs.UnplaceSign( bp[ 'sign_id' ], 'VimspectorBP' ) else: bp[ 'sign_id' ] = self._next_sign_id self._next_sign_id += 1 line = bp[ 'line' ] if 'server_bp' in bp: server_bp = bp[ 'server_bp' ] line = server_bp.get( 'line', line ) verified = server_bp[ 'verified' ] else: verified = self._connection is None sign = ( 'vimspectorBPDisabled' if bp[ 'state' ] != 'ENABLED' or not verified else 'vimspectorBPLog' if 'logMessage' in bp[ 'options' ] else 'vimspectorBPCond' if 'condition' in bp[ 'options' ] or 'hitCondition' in bp[ 'options' ] else 'vimspectorBP' ) if utils.BufferExists( file_name ): signs.PlaceSign( bp[ 'sign_id' ], 'VimspectorBP', sign, file_name, line )
def _DisplayPC(self): frame = self._current_frame if not frame: return self._UndisplayPC(clear_pc=False) # FIXME: Do we relly need to keep using up IDs ? self._signs['vimspectorPC'] = self._next_sign_id self._next_sign_id += 1 sign = 'vimspectorPC' # If there's also a breakpoint on this line, use vimspectorPCBP for bp in self._breakpoints.get(frame['source']['path'], []): if 'line' not in bp: continue if bp['line'] == frame['line']: sign = 'vimspectorPCBP' break try: signs.PlaceSign(self._signs['vimspectorPC'], 'VimspectorCode', sign, frame['source']['path'], frame['line']) except vim.error as e: # Ignore 'invalid buffer name' if 'E158' not in str(e): raise
def SetCurrentFrame( self, frame ): """Returns True if the code window was updated with the frame, False otherwise. False means either the frame is junk, we couldn't find the file (or don't have the data) or the code window no longer exits.""" if self._signs[ 'vimspectorPC' ]: signs.UnplaceSign( self._signs[ 'vimspectorPC' ], 'VimspectorCode' ) self._signs[ 'vimspectorPC' ] = None if not frame or not frame.get( 'source' ): return False if 'path' not in frame[ 'source' ]: return False self._signs[ 'vimspectorPC' ] = self._next_sign_id self._next_sign_id += 1 try: signs.PlaceSign( self._signs[ 'vimspectorPC' ], 'VimspectorCode', 'vimspectorPC', frame[ 'source' ][ 'path' ], frame[ 'line' ] ) except vim.error as e: # Ignore 'invalid buffer name' if 'E158' not in str( e ): raise if not self._window.valid: return False utils.JumpToWindow( self._window ) try: utils.OpenFileInCurrentWindow( frame[ 'source' ][ 'path' ] ) except vim.error: self._logger.exception( 'Unexpected vim error opening file {}'.format( frame[ 'source' ][ 'path' ] ) ) return False # SIC: column is 0-based, line is 1-based in vim. Why? Nobody knows. # Note: max() with 0 because some debug adapters (go) return 0 for the # column. try: self._window.cursor = ( frame[ 'line' ], max( frame[ 'column' ] - 1, 0 ) ) except vim.error: self._logger.exception( "Unable to jump to %s:%s in %s, maybe the file " "doesn't exist", frame[ 'line' ], frame[ 'column' ], frame[ 'source' ][ 'path' ] ) return False self.current_syntax = utils.ToUnicode( vim.current.buffer.options[ 'syntax' ] ) return True
def _ShowBreakpoints(self): for file_name, line_breakpoints in self._line_breakpoints.items(): for bp in line_breakpoints: self._SignToLine(file_name, bp) if 'sign_id' in bp: signs.UnplaceSign(bp['sign_id'], 'VimspectorBP') else: bp['sign_id'] = self._next_sign_id self._next_sign_id += 1 sign = ('vimspectorBPDisabled' if bp['state'] != 'ENABLED' else 'vimspectorBPCond' if 'condition' in bp['options'] else 'vimspectorBP') signs.PlaceSign(bp['sign_id'], 'VimspectorBP', sign, file_name, bp['line'])
def ShowBreakpoints( self ): self._UndisplaySigns() for file_name, breakpoints in self._breakpoints.items(): for breakpoint in breakpoints: if 'line' not in breakpoint: continue sign_id = self._next_sign_id self._next_sign_id += 1 self._signs[ 'breakpoints' ].append( sign_id ) signs.PlaceSign( sign_id, 'VimspectorCode', 'vimspectorBP' if breakpoint[ 'verified' ] else 'vimspectorBPDisabled', file_name, breakpoint[ 'line' ] )
def _DisplayPC(self): frame = self._current_frame if not frame: return self._UndisplayPC(clear_pc=False) # FIXME: Do we relly need to keep using up IDs ? self._signs['vimspectorPC'] = self._next_sign_id self._next_sign_id += 1 # If there's also a breakpoint on this line, use vimspectorPCBP sign = 'vimspectorPCBP' if self._IsBreakpointPresentAt( frame['source']['path'], frame['line']) else 'vimspectorPC' if utils.BufferExists(frame['source']['path']): signs.PlaceSign(self._signs['vimspectorPC'], 'VimspectorCode', sign, frame['source']['path'], frame['line'])
def ShowBreakpoints(self): self._UndisplaySigns() for file_name, breakpoints in self._breakpoints.items(): for breakpoint in breakpoints: if 'line' not in breakpoint: continue sign_id = self._next_sign_id self._next_sign_id += 1 self._signs['breakpoints'].append(sign_id) signs.PlaceSign( sign_id, 'VimspectorCode', 'vimspectorBP' if breakpoint['verified'] else 'vimspectorBPDisabled', file_name, breakpoint['line']) # We need to also check if there's a breakpoint on this PC line and chnge # the PC self._DisplayPC()
def _DrawStackTrace( self, thread: Thread ): if not thread.IsExpanded(): return if self._current_frame_sign_id: signs.UnplaceSign( self._current_frame_sign_id, 'VimspectorStackTrace' ) else: self._current_frame_sign_id = 2 for frame in thread.stacktrace: if frame.get( 'source' ): source = frame[ 'source' ] else: source = { 'name': '<unknown>' } if 'name' not in source: source[ 'name' ] = os.path.basename( source.get( 'path', 'unknwon' ) ) if frame.get( 'presentationHint' ) == 'label': # Sigh. FOr some reason, it's OK for debug adapters to completely ignore # the protocol; it seems that the chrome adapter sets 'label' and # doesn't set 'line' line = utils.AppendToBuffer( self._buf, ' {0}: {1}'.format( frame[ 'id' ], frame[ 'name' ] ) ) else: line = utils.AppendToBuffer( self._buf, ' {0}: {1}@{2}:{3}'.format( frame[ 'id' ], frame[ 'name' ], source[ 'name' ], frame[ 'line' ] ) ) if ( self._current_frame is not None and self._current_frame[ 'id' ] == frame[ 'id' ] ): signs.PlaceSign( self._current_frame_sign_id, 'VimspectorStackTrace', 'vimspectorCurrentFrame', self._buf.name, line ) self._line_to_frame[ line ] = ( thread, frame )