Esempio n. 1
0
def run_build(window: sublime.Window, on_output_callback,
              args) -> core.awaitable[int]:
    global on_finished_futures
    global id
    id += 1
    future = core.create_future()
    on_finished_futures[id] = future
    on_output_callbacks[id] = on_output_callback
    window.run_command("debugger_build_exec", {
        "id": id,
        "args": args,
    })

    try:
        exit_code = yield from future
        return exit_code

    except core.CancelledError as e:
        core.log_info("Cancel build")
        window.run_command("debugger_build_exec", {
            "id": id,
            "args": {
                "kill": True
            },
        })
        raise e
Esempio n. 2
0
def update_diagnostics_panel(window: sublime.Window):
    assert window, "missing window!"
    base_dir = get_project_path(window)

    panel = ensure_diagnostics_panel(window)
    if not panel and not window.is_valid():
        return
    assert panel, "must have a panel now!"

    diagnostics_by_file = get_window_diagnostics(window)
    if diagnostics_by_file is not None:
        active_panel = window.active_panel()
        is_active_panel = (active_panel == "output.diagnostics")
        panel.settings().set("result_base_dir", base_dir)
        panel.set_read_only(False)
        if diagnostics_by_file:
            to_render = []
            for file_path, source_diagnostics in diagnostics_by_file.items():
                try:
                    relative_file_path = os.path.relpath(file_path, base_dir) if base_dir else file_path
                except ValueError:
                    relative_file_path = file_path
                if source_diagnostics:
                    to_render.append(format_diagnostics(relative_file_path, source_diagnostics))
            panel.run_command("code_intel_update_panel", {"characters": "\n".join(to_render)})
            if settings.auto_show_diagnostics_panel and not active_panel:
                window.run_command("show_panel",
                                   {"panel": "output.diagnostics"})
        else:
            panel.run_command("code_intel_clear_panel")
            if is_active_panel:
                window.run_command("hide_panel",
                                   {"panel": "output.diagnostics"})
        panel.set_read_only(True)
Esempio n. 3
0
	def __init__(self, window: sublime.Window):
		super().__init__()

		# ensure we are being run inside a sublime project
		# if not prompt the user to create one
		project_name = window.project_file_name()
		while not project_name:
			r = sublime.ok_cancel_dialog("Debugger requires a sublime project. Would you like to create a new sublime project?", "Save Project As...")
			if r:
				window.run_command('save_project_and_workspace_as')
			else:
				raise core.Error("Debugger must be run inside a sublime project")

			project_name = window.project_file_name()

		self.name = project_name
		self.window = window
		self.on_updated: core.Event[None] = core.Event()

		self.tasks: List[Task] = []
		self.compounds: List[ConfigurationCompound] = []
		self.configurations: List[Configuration] = []
		self.configuration_or_compound: Optional[Union[Configuration, ConfigurationCompound]] = None

		self.external_terminal_kind = 'platform'
		self.ui_scale = 12
		self.bring_window_to_front_on_pause = False

		# add the empty debugger configurations settings if needed
		data = window.project_data() or {}
		data.setdefault('debugger_configurations', [])
		window.set_project_data(data)

		self.disposables += Settings.updated.add(self.reload)
		self.reload()
Esempio n. 4
0
    def __init__(self, window: sublime.Window, on_output, args):
        global debugger_exec_for_id
        global id
        id += 1
        debugger_exec_for_id[id] = self

        self.future = core.create_future()
        self.on_output_callback = on_output

        window.run_command("debugger_exec", {
            "id": id,
            "args": args,
        })

        async def kill_if_canceled():
            try:
                await self.future
            except core.CancelledError as e:
                core.log_info("Cancel task")
                window.run_command("debugger_exec", {
                    "id": id,
                    "args": {
                        "kill": True
                    },
                })
                raise e

        core.run(kill_if_canceled())
Esempio n. 5
0
def select_configuration(
        window: sublime.Window,
        index: int) -> core.awaitable[Optional[Configuration]]:
    try:
        configs = all_configurations(window)
    except Exception as e:
        core.display(e)
        show_settings(window)

    done = core.main_loop.create_future()
    names = list(map(lambda x: x.name, configs)) + ["-"
                                                    ] + ["Add configuration"]

    index = yield from core.sublime_show_quick_panel_async(
        window, names, index)
    if index < 0:
        return None
    if index >= len(configs):
        project = window.project_file_name()
        if project:
            sublime.run_command("new_window")
            window = sublime.active_window()
            window.open_file(project)
        else:
            window.run_command(
                'edit_settings',
                {"base_file": "${packages}/sublime_db/debug.sublime-settings"})
        return None
    return configs[index]
Esempio n. 6
0
def send_terminus_repl(window: sublime.Window, code_block: str):
    # ensure code block ends with newline, so that it will be executed in REPL
    if not code_block.endswith("\n"):
        code_block += "\n"
    window.run_command("terminus_send_string", {
        "string": code_block,
        "tag": JULIA_REPL_TAG
    })
Esempio n. 7
0
def show_error_result(window: sublime.Window, message: str) -> None:
    """show error panel"""

    panel = window.create_output_panel(ERROR_RESPONSE_PANEL_NAME)
    panel.set_read_only(False)
    panel.run_command(
        "append",
        {"characters": message},
    )
    window.run_command("show_panel",
                       {"panel": f"output.{ERROR_RESPONSE_PANEL_NAME}"})
Esempio n. 8
0
def update_diagnostics_panel(window: sublime.Window):
    assert window, "missing window!"

    if not window.is_valid():
        debug('ignoring update to closed window')
        return

    base_dir = get_project_path(window)

    diagnostics_by_file = get_window_diagnostics(window)
    if diagnostics_by_file is not None:

        active_panel = window.active_panel()
        is_active_panel = (active_panel == "output.diagnostics")

        if diagnostics_by_file:
            panel = ensure_diagnostics_panel(window)
            assert panel, "must have a panel now!"
            panel.settings().set("result_base_dir", base_dir)

            auto_open_panel = False
            to_render = []
            for file_path, source_diagnostics in diagnostics_by_file.items():
                try:
                    relative_file_path = os.path.relpath(
                        file_path, base_dir) if base_dir else file_path
                except ValueError:
                    relative_file_path = file_path
                if source_diagnostics:
                    formatted = format_diagnostics(relative_file_path,
                                                   source_diagnostics)
                    if formatted:
                        to_render.append(formatted)
                        if not auto_open_panel:
                            auto_open_panel = has_relevant_diagnostics(
                                source_diagnostics)

            panel.set_read_only(False)
            panel.run_command("lsp_update_panel",
                              {"characters": "\n".join(to_render)})
            panel.set_read_only(True)

            if settings.auto_show_diagnostics_panel and not active_panel:
                if auto_open_panel:
                    window.run_command("show_panel",
                                       {"panel": "output.diagnostics"})

        else:
            panel = window.find_output_panel("diagnostics")
            if panel:
                panel.run_command("lsp_clear_panel")
                if is_active_panel:
                    window.run_command("hide_panel",
                                       {"panel": "output.diagnostics"})
Esempio n. 9
0
def run(window: sublime.Window, on_output_callback,
        args) -> core.awaitable[None]:
    global on_finished_futures
    global id
    id += 1
    future = core.create_future()
    on_finished_futures[id] = future
    on_output_callbacks[id] = on_output_callback
    print(args)
    window.run_command("debugger_build_exec", {
        "id": id,
        "args": args,
    })
    return future
Esempio n. 10
0
def start_terminus_repl(window: sublime.Window, focus: bool):
    settings = sublime.load_settings(SETTINGS_FILE)
    julia_executable = settings.get("julia_executable_path") or "julia"
    # start in current project environment if available
    cmd = [julia_executable, "--banner=no", "--project"]
    window.run_command(
        "terminus_open", {
            "cmd": cmd,
            "cwd": "${file_path:${folder}}",
            "panel_name": JULIA_REPL_NAME,
            "focus": focus,
            "tag": JULIA_REPL_TAG,
            "env": settings.get("repl_env_variables")
        })
Esempio n. 11
0
def close_window(window: sublime.Window, *, force: bool = False) -> None:
    """Close the given window, discarding unsaved changes if `force` is ``True``.

    :raise ValueError: if any view in the window has unsaved changes
        and `force` is not ``True``.

    .. versionadded:: 1.2
    """
    for view in window.views():
        if view.is_dirty() and not view.is_scratch():
            if force:
                view.set_scratch(True)
            else:
                raise ValueError('A view has unsaved changes.')

    window.run_command('close_window')
Esempio n. 12
0
def sublime_show_input_panel_async(
    window: sublime.Window,
    caption: str,
    initial_text: str,
    on_change: Optional[Callable[[str],
                                 None]] = None) -> awaitable[Optional[str]]:
    result = create_future()
    active_panel = window.active_panel()

    def on_done(value: str) -> None:
        call_soon_threadsafe(result.set_result, value)

    def on_cancel() -> None:
        call_soon_threadsafe(result.set_result, None)

    view = window.show_input_panel(caption, initial_text, on_done, on_change,
                                   on_cancel)
    r = yield from result
    # restore the previous panel
    window.run_command('show_panel', {'panel': '{}'.format(active_panel)})
    return r
Esempio n. 13
0
def close_window(window: sublime.Window, *, force: bool = False) -> None:
    """Close the given window, discarding unsaved changes if `force` is ``True``.

    :raise ValueError: if any view in the window has unsaved changes
        and `force` is not ``True``.

    .. versionadded:: 1.2
    """
    unsaved = [
        view for view in window.views()
        if view.is_dirty() and not view.is_scratch()
    ]

    if unsaved:
        if not force:
            raise ValueError('A view has unsaved changes.')

        with _temporarily_scratch_unsaved_views(unsaved):
            window.run_command('close_window')
    else:
        window.run_command('close_window')
Esempio n. 14
0
def open_settings(window: sublime.Window):
    window.run_command(
        'edit_settings',
        {'base_file': '${packages}/Debugger/debugger.sublime-settings'})
Esempio n. 15
0
	def __init__(self, window: sublime.Window) -> None:

		# ensure we are being run inside a sublime project
		# if not prompt the user to create one
		while True:
			data = window.project_data()
			project_name = window.project_file_name()
			while not data or not project_name:
				r = sublime.ok_cancel_dialog("Debugger requires a sublime project. Would you like to create a new sublime project?", "Save Project As...")
				if r:
					window.run_command('save_project_and_workspace_as')
				else:
					raise core.Error("Debugger must be run inside a sublime project")

			# ensure we have debug configurations added to the project file
			data.setdefault('settings', {}).setdefault('debug.configurations', [])
			window.set_project_data(data)
			break
		self.project = DebuggerProject(window)

		autocomplete = Autocomplete.create_for_window(window)

		self.window = window
		self.disposeables = [] #type: List[Any]
		
		self.breakpoints = Breakpoints();

		self.callstack_panel = CallStackPanel()
		self.breakpoints_panel = BreakpointsPanel(self.breakpoints)
		self.debugger_panel = DebuggerPanel(self, self.breakpoints_panel)

		def on_state_changed(state: int) -> None:
			if state == DebuggerStateful.stopped:
				self.debugger_panel.setState(STOPPED)
				self.show_console_panel()
			elif state == DebuggerStateful.running:
				self.debugger_panel.setState(RUNNING)
			elif state == DebuggerStateful.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 == DebuggerStateful.stopping or state == DebuggerStateful.starting:
				self.debugger_panel.setState(LOADING)

		def on_scopes(scopes: List[dap.Scope]) -> None:
			self.variables_panel.set_scopes(scopes)

		def on_selected_frame(thread: Optional[dap.Thread], frame: Optional[dap.StackFrame]) -> None:
			if frame and thread and frame.source:
				self.source_provider.select(frame.source, frame.line, thread.stopped_text)
			else:
				self.source_provider.clear()

		def on_output(event: dap.OutputEvent) -> None:
			self.terminal.program_output(self.debugger.adapter, event)

		def on_threads_stateful(threads: Any):
			self.callstack_panel.update(self.debugger, threads)


		from .diff import DiffCollection
		from .terminal import Terminal
		def on_terminal_added(terminal: Terminal):
			component = TerminalComponent(terminal)

			panel = TabbedPanelItem(id(terminal), component, terminal.name(), 0, component.action_buttons())
			def on_modified():
				self.panels.modified(panel)

			terminal.on_updated.add(on_modified)

			self.panels.add([panel])

		def on_terminal_removed(terminal: Terminal):
			self.panels.remove(id(terminal))

		terminals = DiffCollection(on_terminal_added, on_terminal_removed)
		
		def on_terminals(list: Any):
			terminals.update(list)

		self.debugger = DebuggerStateful(
			self.breakpoints,
			on_state_changed=on_state_changed,
			on_scopes=on_scopes,
			on_output=on_output,
			on_selected_frame=on_selected_frame,
			on_threads_stateful=on_threads_stateful,
			on_terminals=on_terminals)


		self.variables_panel = VariablesPanel(self.breakpoints, self.debugger.watch)

		self.panel = OutputPhantomsPanel(window, 'Debugger')
		self.panel.show()
		self.view = self.panel.view #type: sublime.View

		self.persistance = PersistedData(project_name)
		self.load_data()
		self.load_settings_and_configurations()

		self.disposeables.extend([
			self.panel,
		])

		self.disposeables.append(WindowSettingsCallback(self.window, self.on_settings_updated))

		phantom_location = self.panel.phantom_location()
		phantom_view = self.panel.phantom_view()
		self.disposeables.extend([
			ui.Phantom(self.debugger_panel, phantom_view, sublime.Region(phantom_location, phantom_location + 0), sublime.LAYOUT_INLINE),
		])

		callstack_panel_item = TabbedPanelItem(id(self.callstack_panel), self.callstack_panel, "Call Stack", 0)
		variables_panel_item = TabbedPanelItem(id(self.variables_panel), self.variables_panel, "Variables", 1)

		self.terminal = DebuggerTerminal(
			on_run_command=self.on_run_command, 
			on_clicked_source=self.on_navigate_to_source
		)
		terminal_component = TerminalComponent(self.terminal)
		terminal_panel_item = TabbedPanelItem(id(self.terminal), terminal_component, self.terminal.name(), 0)
		modules_panel = TabbedPanelItem(id(self.debugger.modules), ModulesView(self.debugger.modules), "Modules", 1)
		sources_panel = TabbedPanelItem(id(self.debugger.sources), SourcesView(self.debugger.sources), "Sources", 1)

		self.terminal.log_info('Opened In Workspace: {}'.format(os.path.dirname(project_name)))

		self.panels = Panels(phantom_view, phantom_location + 1, 3)
		self.panels.add([
			callstack_panel_item,
			variables_panel_item,
			terminal_panel_item,
			modules_panel,
			sources_panel
		])

		view_hover = ViewHoverProvider(self.project, self.debugger)
		self.disposeables.append(view_hover)

		self.source_provider = ViewSelectedSourceProvider(self.project, self.debugger)
		self.disposeables.append(self.source_provider)

		self.breakpoints_provider = BreakpointCommandsProvider(self.project, self.debugger, self.breakpoints)
		self.disposeables.append(self.breakpoints_provider)
Esempio n. 16
0
def toggle_output_panel(window: Window, panel_type: str) -> None:
    panel_name = "output.{}".format(panel_type)
    command = "{}_panel".format("hide" if window.active_panel() ==
                                panel_name else "show")
    window.run_command(command, {"panel": panel_name})
    def __init__(self, window: sublime.Window):
        super().__init__()

        # ensure we are being run inside a sublime project
        # if not prompt the user to create one
        while True:
            data = window.project_data()
            project_name = window.project_file_name()
            while not project_name:
                r = sublime.ok_cancel_dialog(
                    "Debugger requires a sublime project. Would you like to create a new sublime project?",
                    "Save Project As...")
                if r:
                    window.run_command('save_project_and_workspace_as')
                else:
                    raise core.Error(
                        "Debugger must be run inside a sublime project")

            # ensure we have debug configurations added to the project file
            data.setdefault('settings', {}).setdefault('debug.configurations',
                                                       [])
            window.set_project_data(data)
            break

        self.name = project_name
        self.window = window
        self.on_updated: core.Event[None] = core.Event()

        self.compounds: List[ConfigurationCompound] = []
        self.configurations: List[Configuration] = []

        self.external_terminal_kind = 'platform'
        self.ui_scale = 12
        self.bring_window_to_front_on_pause = False

        self.panel = self.window.create_output_panel("Debugger")
        self.panel_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.panel.run_command('insert', {'characters': _phantom_text})
        settings = self.panel.settings()
        settings.set("margin", 0)
        settings.set('line_padding_top', 1)
        settings.set('gutter', False)
        settings.set('word_wrap', False)
        settings.set('line_spacing', 0)
        settings.set('context_menu', 'Widget Debug.sublime-menu')

        self.panel.sel().clear()

        # hack to get view to not freak out when clicking the edge of the window
        self.panel.set_viewport_position((_panel_position, 0), animate=False)

        async def later():
            await core.sleep(0)
            self.panel.set_viewport_position((_panel_position, 0),
                                             animate=False)

        core.run(later())
        self.reload()