def __init__(self, view: sublime.View, line: int, text: str): pt_current_line = view.text_point(line, 0) pt_prev_line = view.text_point(line - 1, 0) pt_next_line = view.text_point(line + 1, 0) line_prev = view.line(pt_current_line) line_current = view.line(pt_prev_line) self.top_line = ui.Phantom(UnderlineComponent(), view, line_current, sublime.LAYOUT_BELOW) self.text = ui.Phantom( SelectedLineText(text), view, sublime.Region(pt_next_line - 1, pt_next_line - 1), sublime.LAYOUT_INLINE) self.bottom_line = ui.Phantom(UnderlineComponent(), view, line_prev, sublime.LAYOUT_BELOW)
def __init__(self, window: sublime.Window, name: str) -> None: self.header_text = "" self.name = name self.window = window self.view = window.create_output_panel(name) self.show() # we need enough space to place our phantoms in increasing regions (1, 1), (1, 2)... etc # otherwise they will get reordered when one of them gets redrawn # we use new lines so we don't have extra space on the rhs self.view.run_command('debug_output_phantoms_panel_setup') settings = self.view.settings() # cover up the addition space we added during the insert # the additional space is so we can have an input bar at the top of the debugger # removes some additional padding on the top of the view settings.set("margin", 0) settings.set('line_padding_top', PADDING_TOP_COMMAND_HIDE) settings.set('line_padding_bottom', -3) settings.set('gutter', False) settings.set('word_wrap', False) settings.set('line_spacing', 0) settings.set('context_menu', 'Widget Debug.sublime-menu') self.view.sel().clear() self.hack_to_get_view_to_not_freak_out_when_you_click_on_the_edge() self.input_handler = None #type: Optional[PanelInputHandler] OutputPhantomsPanel.panels[self.view.id()] = self self.promptPhantom = ui.Phantom(CommandPrompComponent(""), self.view, sublime.Region(1, 1))
def add_selected_stack_frame_component(self, view: sublime.View, line: int) -> None: if self.selectedFrameComponent: self.selectedFrameComponent.dispose() self.selectedFrameComponent = None if not self.debugAdapterClient: return if not self.debugAdapterClient.selected_frame: return pt = view.text_point(line + 1, 0) max = view.viewport_extent()[0]/view.em_width() - 3 pt_current_line = view.text_point(line, 0) line_current = view.line(pt_current_line) region = sublime.Region(pt-1, pt-1) layout = sublime.LAYOUT_INLINE if line_current.b - line_current.a > max: pt = view.text_point(line - 1, 0) region = sublime.Region(pt, pt) layout = sublime.LAYOUT_BELOW variables = ui.Segment(items = [ ui.Button(self.OnResume, items = [ ui.Img(ui.Images.shared.play) ]), ui.Button(self.OnStepOver, items = [ ui.Img(ui.Images.shared.down) ]), ui.Button(self.OnStepOut, items = [ ui.Img(ui.Images.shared.left) ]), ui.Button(self.OnStepIn, items = [ ui.Img(ui.Images.shared.right) ]), ui.Label(self.stopped_reason, padding_left = 1, padding_right = 1, color = 'secondary') ]) self.selectedFrameComponent = ui.Phantom(variables, view, region, layout)
def a() -> core.awaitable[None]: view = yield from core.sublime_open_file_async(sublime.active_window(), breakpoint.file, breakpoint.line) at = view.text_point(breakpoint.line - 1, 0) view.sel().clear() self.clearBreakpointInformation() self.breakpointInformation = ui.Phantom(BreakpointInlineComponent(breakpoints = self.breakpoints, breakpoint = breakpoint), view, sublime.Region(at, at), sublime.LAYOUT_BELOW)
def __init__(self, window: sublime.Window) -> None: print('new Main for window', window.id()) self.window = window self.disposeables = [] #type: List[Any] self.breakpoints = Breakpoints() self.view = None #type: Optional[sublime.View] self.eventLog = EventLogComponent() self.variablesComponent = VariablesComponent() self.callstackComponent = CallStackComponent() self.debuggerComponent = DebuggerComponent(self.breakpoints, self) self.debugAdapterClient = None #type: Optional[DebugAdapterClient] self.selectedFrameComponent = None #type: Optional[ui.Phantom] self.breakpointInformation = None #type: Optional[ui.Phantom] self.pausedWithError = False self.process = None #type: Optional[Process] self.disconnecting = False self.project_name = window.project_file_name() or "user" data = config.persisted_for_project(self.project_name) config_name = data.get('config_name') config_maybe_at_index = data.get('config_maybe_at_index') for bp in data.get('breakpoints', []): self.breakpoints.add(Breakpoint.from_json(bp)) if config_name: self.configuration = get_configuration_for_name(window, config_name, config_maybe_at_index) else: self.configuration = None if self.configuration: self.debuggerComponent.set_name(self.configuration.name) else: self.debuggerComponent.set_name('select config') self.stopped_reason = '' self.path = window.project_file_name() if self.path: self.path = os.path.dirname(self.path) self.eventLog.Add('Opened In Workspace: {}'.format(self.path)) else: self.eventLog.AddStderr('warning: debugger opened in a window that is not part of a project') print('Creating a window: h') self.disposeables.extend([ ui.view_gutter_hovered.add(self.on_gutter_hovered), ui.view_text_hovered.add(self.on_text_hovered), ui.view_drag_select.add(self.on_drag_select), ]) mode = get_setting(window.active_view(), 'display') if mode == 'window': sublime.run_command("new_window") new_window = sublime.active_window() output = new_window.new_file() new_window.set_minimap_visible(False) new_window.set_sidebar_visible(False) new_window.set_tabs_visible(False) new_window.set_menu_visible(False) new_window.set_status_bar_visible(False) elif mode == 'view': output = self.window.new_file() elif mode == 'output': output = self.window.create_output_panel('debugger') self.window.run_command('show_panel', { 'panel': 'output.debugger' }) else: core.display('expected setting "mode" to be one of "window", "view" or "output", found "{}"'.format(mode)) return output.run_command('insert', { 'characters': " " }) output.set_scratch(True) output.set_read_only(True) output.set_name('Debugger') view_settings = output.settings() view_settings.set("is_widget", True) view_settings.set("gutter", False) view_settings.set("margin", 0) view_settings.set("always_show_minimap_viewport", False) self.view = output self.disposeables.extend([ ui.Phantom(self.debuggerComponent, output, sublime.Region(1, 1), sublime.LAYOUT_INLINE), ui.Phantom(self.callstackComponent, output, sublime.Region(1, 2), sublime.LAYOUT_INLINE), ui.Phantom(self.variablesComponent, output, sublime.Region(1, 3), sublime.LAYOUT_INLINE), ui.Phantom(self.eventLog, output, sublime.Region(1, 4), sublime.LAYOUT_INLINE) ]) self.breakpoints.onRemovedBreakpoint.add(lambda b: self.clearBreakpointInformation()) self.breakpoints.onChangedBreakpoint.add(self.onChangedBreakpoint) self.breakpoints.onChangedFilter.add(self.onChangedFilter) self.breakpoints.onSelectedBreakpoint.add(self.onSelectedBreakpoint)
def __init__(self, window: sublime.Window) -> None: data = window.project_data() project_name = window.project_file_name() if not data or not project_name: sublime.error_message( "Debugger must be run inside a sublime project") return # ensure we have debug configurations added to the project file data.setdefault('settings', {}).setdefault('debug.configurations', []) window.set_project_data(data) ui.set_create_input_handler(window, self.create_input_handler) self.input_open = False self.window = window self.disposeables = [] #type: List[Any] self.breakpoints = Breakpoints() self.console_panel = ConsolePanel(self.open_repl_console) self.variables_panel = VariablesPanel() self.callstack_panel = CallStackPanel() self.breakpoints_panel = BreakpointsComponent( self.breakpoints, self.onSelectedBreakpoint) self.pages_panel = TabbedPanel([ ("Breakpoints", self.breakpoints_panel, None), ("Call Stack", self.callstack_panel, None), ("Console", self.console_panel, self.console_panel.change_filter), ], 0) self.debugger_panel = DebuggerPanel(self.breakpoints, self) self.selected_frame_line = None #type: Optional[SelectedLine] self.selected_frame_generated_view = None #type: Optional[sublime.View] self.breakpointInformation = None #type: Optional[Any] def on_state_changed(state: int) -> None: if state == DebuggerState.stopped: self.breakpoints.clear_breakpoint_results() self.debugger_panel.setState(STOPPED) self.show_console_panel() elif state == DebuggerState.running: self.debugger_panel.setState(RUNNING) elif state == DebuggerState.paused: self.debugger_panel.setState(PAUSED) if get_setting(self.view, 'bring_window_to_front_on_pause', False): # is there a better way to bring sublime to the front?? # this probably doesn't work for most people. subl needs to be in PATH file = self.window.active_view().file_name() if file: # ignore any errors try: subprocess.call(["subl", file]) except Exception: pass self.show_call_stack_panel() elif state == DebuggerState.stopping or state == DebuggerState.starting: self.debugger_panel.setState(LOADING) def on_threads(threads: List[Thread]) -> None: self.callstack_panel.update(self.debugger, threads) def on_scopes(scopes: List[Scope]) -> None: self.variables_panel.set_scopes(scopes) def on_selected_frame(thread: Optional[Thread], frame: Optional[StackFrame]) -> None: if frame and thread: self.run_async(self.navigate_to_frame(thread, frame)) else: self.dispose_selected_frame() def on_output(event: OutputEvent) -> None: category = event.category msg = event.text variablesReference = event.variablesReference if variablesReference and self.debugger.adapter: # this seems to be what vscode does it ignores the actual message here. # Some of the messages are junk like "output" that we probably don't want to display @core. async def appendVariabble() -> core.awaitable[None]: variables = yield from self.debugger.adapter.GetVariables( variablesReference) for variable in variables: variable.name = "" # this is what vs code does? self.console_panel.AddVariable(variable) self.pages_panel.modified(2) # this could make variable messages appear out of order. Do we care?? self.run_async(appendVariabble()) elif category == "stdout": self.console_panel.AddStdout(msg) self.pages_panel.modified(2) elif category == "stderr": self.console_panel.AddStderr(msg) self.pages_panel.modified(2) elif category == "telemetry": pass elif category == "output": self.console_panel.AddStdout(msg) self.pages_panel.modified(2) elif category == "error": self.console_panel.AddStderr(msg) self.pages_panel.modified(2) elif category == "info": self.console_panel.Add(msg) self.pages_panel.modified(2) else: self.console_panel.AddOutputOther(msg) self.pages_panel.modified(2) self.debugger = DebuggerState(on_state_changed=on_state_changed, on_threads=on_threads, on_scopes=on_scopes, on_output=on_output, on_selected_frame=on_selected_frame) self.panel = OutputPhantomsPanel(window, 'Debugger') self.panel.show() self.view = self.panel.view #type: sublime.View self.persistance = PersistedData(project_name) for breakpoint in self.persistance.load_breakpoints(): self.breakpoints.add(breakpoint) self.load_configurations() self.stopped_reason = '' self.path = window.project_file_name() if self.path: self.path = os.path.dirname(self.path) self.console_panel.Add('Opened In Workspace: {}'.format(self.path)) else: self.console_panel.AddStderr( 'warning: debugger opened in a window that is not part of a project' ) print('Creating a window: h') self.disposeables.extend([ self.panel, ui.view_gutter_hovered.add(self.on_gutter_hovered), ui.view_text_hovered.add(self.on_text_hovered), ui.view_drag_select.add(self.on_drag_select), ]) offset = self.panel.phantom_location() self.disposeables.extend([ ui.Phantom(self.debugger_panel, self.view, sublime.Region(offset, offset + 0), sublime.LAYOUT_INLINE), ui.Phantom(self.pages_panel, self.view, sublime.Region(offset, offset + 1), sublime.LAYOUT_INLINE), ui.Phantom(self.variables_panel, self.view, sublime.Region(offset, offset + 2), sublime.LAYOUT_INLINE), ]) self.breakpoints.onRemovedBreakpoint.add( lambda b: self.clearBreakpointInformation()) self.breakpoints.onChangedBreakpoint.add(self.onChangedBreakpoint) self.breakpoints.onChangedFilter.add(self.onChangedFilter) self.breakpoints.onSelectedBreakpoint.add(self.onSelectedBreakpoint) active_view = self.window.active_view() if active_view: self.disposeables.append( register_on_changed_setting(active_view, self.on_settings_updated)) else: print('Failed to find active view to listen for settings changes')