Esempio n. 1
0
    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)
Esempio n. 2
0
	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))
Esempio n. 3
0
	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)
Esempio n. 4
0
		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)
Esempio n. 5
0
	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)
Esempio n. 6
0
    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')