Esempio n. 1
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. 2
0
	def forWindow(window: sublime.Window, create: bool = False) -> 'Optional[Main]':
		instance = Main.instances.get(window.id())
		if not instance and create:
			main = Main(window)
			Main.instances[window.id()] = main
			return main
		return instance
Esempio n. 3
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. 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 open_file(window: sublime.Window,
              file_path: str,
              flags: int = 0,
              group: int = -1) -> Promise[Optional[sublime.View]]:
    """Open a file asynchronously. It is only safe to call this function from the UI thread."""

    # window.open_file brings the file to focus if it's already opened, which we don't want.
    # So we first check if there's already a view for that file.
    view = window.find_open_file(file_path)
    if view:
        return Promise.resolve(view)

    view = window.open_file(file_path, flags, group)
    if not view.is_loading():
        # It's already loaded. Possibly already open in a tab.
        return Promise.resolve(view)

    # Is the view opening right now? Then return the associated unresolved promise
    for fn, value in opening_files.items():
        if fn == file_path or os.path.samefile(fn, file_path):
            # Return the unresolved promise. A future on_load event will resolve the promise.
            return value[0]

    # Prepare a new promise to be resolved by a future on_load event (see the event listener in main.py)
    def fullfill(resolve: ResolveFunc[Optional[sublime.View]]) -> None:
        global opening_files
        # Save the promise in the first element of the tuple -- except we cannot yet do that here
        opening_files[file_path] = (None, resolve)  # type: ignore

    promise = Promise(fullfill)
    tup = opening_files[file_path]
    # Save the promise in the first element of the tuple so that the for-loop above can return it
    opening_files[file_path] = (promise, tup[1])
    return promise
Esempio n. 6
0
 def open_location(window: sublime.Window,
                   location: Tuple[str, str, Tuple[int, int]]) -> None:
     fname, file_path_and_row_col, rowcol = location
     row, col = rowcol
     debug("opening location", file_path_and_row_col)
     window.open_file(file_path_and_row_col,
                      sublime.ENCODED_POSITION | sublime.FORCE_GROUP)
Esempio n. 7
0
def update_diagnostics_panel(window: sublime.Window):
    assert window, "missing window!"
    base_dir = get_project_path(window)

    panel = ensure_diagnostics_panel(window)
    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():
                relative_file_path = os.path.relpath(
                    file_path, base_dir) if base_dir else file_path
                if source_diagnostics:
                    to_render.append(
                        format_diagnostics(relative_file_path,
                                           source_diagnostics))
            panel.run_command("lsp_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("lsp_clear_panel")
            if settings.auto_show_diagnostics_panel and is_active_panel:
                window.run_command("hide_panel",
                                   {"panel": "output.diagnostics"})
        panel.set_read_only(True)
Esempio n. 8
0
def get_project_path(window: sublime.Window) -> 'Optional[str]':
    """
    Returns the common root of all open folders in the window
    """
    if len(window.folders()):
        folder_paths = window.folders()
        return folder_paths[0]
    else:
        view = window.active_view()
        if view:
            filename = view.file_name()
            if filename:
                project_path = os.path.dirname(filename)
                debug(
                    "Couldn't determine project directory since no folders are open!",
                    "Using", project_path, "as a fallback.")
                return project_path
            else:
                debug(
                    "Couldn't determine project directory since no folders are open",
                    "and the current file isn't saved on the disk.")
                return None
        else:
            debug("No view is active in current window")
            return None  # https://github.com/tomv564/LSP/issues/219
Esempio n. 9
0
 def forWindow(window: sublime.Window,
               create: bool = False) -> 'Optional[DebuggerInterface]':
     instance = DebuggerInterface.instances.get(window.id())
     if not instance and create:
         main = DebuggerInterface(window)
         DebuggerInterface.instances[window.id()] = main
         return main
     return instance
Esempio n. 10
0
def sublime_show_quick_panel_async(window: sublime.Window, items: List[str],
                                   selected_index: int) -> awaitable[int]:
    done = main_loop.create_future()
    window.show_quick_panel(items,
                            lambda index: done.set_result(index),
                            selected_index=selected_index)
    r = yield from done
    return r
Esempio n. 11
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. 12
0
 def select_entry(window: sublime.Window,
                  locations: List[Tuple[str, str, Tuple[int, int]]],
                  idx: int, orig_view: sublime.View) -> None:
     if idx >= 0:
         open_location(window, locations[idx])
     else:
         if orig_view:
             window.focus_view(orig_view)
Esempio n. 13
0
def sublime_show_quick_panel_async(window: sublime.Window, items: List[str],
                                   selected_index: int) -> awaitable[int]:
    done = create_future()
    window.show_quick_panel(
        items,
        lambda index: call_soon_threadsafe(done.set_result, index),
        selected_index=selected_index)
    r = yield from done
    return r
Esempio n. 14
0
def destroy_output_panels(window: sublime.Window) -> None:
    for field in filter(lambda a: not a.startswith('__'),
                        PanelName.__dict__.keys()):
        panel_name = getattr(PanelName, field)
        panel = window.find_output_panel(panel_name)
        if panel and panel.is_valid():
            panel.settings().set("syntax",
                                 "Packages/Text/Plain text.tmLanguage")
            window.destroy_output_panel(panel_name)
Esempio n. 15
0
def start_window_config(window: sublime.Window, project_path: str, config: ClientConfig,
                        on_created: 'Callable'):
    args, env = get_window_env(window, config)
    config.binary_args = args
    session = create_session(config, project_path, env, settings,
                             on_created=on_created,
                             on_ended=lambda: on_session_ended(window, config.name))
    clients_by_window.setdefault(window.id(), {})[config.name] = session
    debug("{} client registered for window {}".format(config.name, window.id()))
Esempio n. 16
0
 def highlight_entry(window: sublime.Window,
                     locations: List[Tuple[str, str, Tuple[int, int]]],
                     idx: int) -> None:
     fname, file_path_and_row_col, rowcol = locations[idx]
     row, col = rowcol
     window.open_file(file_path_and_row_col,
                      group=window.active_group(),
                      flags=sublime.TRANSIENT | sublime.ENCODED_POSITION
                      | sublime.FORCE_GROUP)
Esempio n. 17
0
def start_client(window: sublime.Window, config: ClientConfig):
    project_path = get_project_path(window)
    if project_path is None:
        return None

    if settings.show_status_messages:
        window.status_message("Starting " + config.name + "...")
    debug("starting in", project_path)

    # Create a dictionary of Sublime Text variables
    variables = window.extract_variables()

    # Expand language server command line environment variables
    expanded_args = list(
        sublime.expand_variables(os.path.expanduser(arg), variables)
        for arg in config.binary_args
    )

    # Override OS environment variables
    env = os.environ.copy()
    for var, value in config.env.items():
        # Expand both ST and OS environment variables
        env[var] = os.path.expandvars(sublime.expand_variables(value, variables))

    client = start_server(expanded_args, project_path, env)
    if not client:
        window.status_message("Could not start " + config.name + ", disabling")
        debug("Could not start", config.binary_args, ", disabling")
        return None

    initializeParams = {
        "processId": client.process.pid,
        "rootUri": filename_to_uri(project_path),
        "rootPath": project_path,
        "capabilities": {
            "textDocument": {
                "completion": {
                    "completionItem": {
                        "snippetSupport": True
                    }
                },
                "synchronization": {
                    "didSave": True
                }
            },
            "workspace": {
                "applyEdit": True
            }
        }
    }
    if config.init_options:
        initializeParams['initializationOptions'] = config.init_options

    client.send_request(
        Request.initialize(initializeParams),
        lambda result: handle_initialize_result(result, client, window, config))
    return client
Esempio n. 18
0
def get_active_views(window: sublime.Window,
                     current_buffer_only: bool) -> List[sublime.View]:
    """Returns all currently visible views"""

    if current_buffer_only:
        group_indexes = [window.active_group()]
    else:
        group_indexes = list(range(window.num_groups()))

    return [window.active_view_in_group(idx)
            for idx in group_indexes]  # type: ignore
Esempio n. 19
0
 def lookup(self, window: sublime.Window) -> WindowManager:
     wm = self._windows.get(window.id())
     if wm:
         return wm
     workspace = ProjectFolders(window)
     window_configs = self._configs.for_window(window)
     state = WindowManager(window=window,
                           workspace=workspace,
                           configs=window_configs)
     self._windows[window.id()] = state
     return state
Esempio n. 20
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. 21
0
def agenda_meta_info_get_or_create_view(window: sublime.Window, meta_info: Agenda.AgendaItemMetaInfo):
    if meta_info.file_name is not None:
        view = window.find_open_file(meta_info.file_name)
        if view is not None:
            return view
        return window.open_file(meta_info.file_name)

    for view in window.views():
        if view.id() == meta_info.view_id:
            return view

    raise ZorgmodeError("Cannot find file for this item")
Esempio n. 22
0
	def for_window(window: sublime.Window, create: bool = False) -> 'Optional[DebuggerInterface]':
		instance = DebuggerInterface.instances.get(window.id())
		if not instance and create:
			try:
				main = DebuggerInterface(window)
				DebuggerInterface.instances[window.id()] = main
				return main
			except dap.Error as e:
				core.log_exception()
		if create:
			instance.show()
		return instance
Esempio n. 23
0
def disable_in_project(window: sublime.Window, config_name: str) -> None:
    project_data = window.project_data()
    if isinstance(project_data, dict):
        project_settings = project_data.setdefault('settings', dict())
        project_lsp_settings = project_settings.setdefault('LSP', dict())
        project_client_settings = project_lsp_settings.setdefault(
            config_name, dict())
        project_client_settings['enabled'] = False
        window.set_project_data(project_data)
    else:
        sublime.message_dialog(
            "Can't disable {} in the current workspace. Ensure that the project is saved first."
            .format(config_name))
Esempio n. 24
0
def update_file_diagnostics(window: sublime.Window, file_path: str, source: str,
                            diagnostics: 'List[Diagnostic]'):
    if diagnostics:
        window_file_diagnostics.setdefault(window.id(), dict()).setdefault(
            file_path, dict())[source] = diagnostics
    else:
        if window.id() in window_file_diagnostics:
            file_diagnostics = window_file_diagnostics[window.id()]
            if file_path in file_diagnostics:
                if source in file_diagnostics[file_path]:
                    del file_diagnostics[file_path][source]
                if not file_diagnostics[file_path]:
                    del file_diagnostics[file_path]
Esempio n. 25
0
 def on_start(cls, window: sublime.Window) -> bool:
     if cls.manages_server():
         server = cls.get_server()
         if server is None or server.get_status() != ServerStatus.READY:
             log_and_show_message('{}: Server not ready'.format(cls.get_displayed_name()))
             return False
     startup_view = window.active_view()
     workspace_folders = [WorkspaceFolder.from_path(folder) for folder in window.folders()]
     message = cls.is_allowed_to_start(window, startup_view, workspace_folders)
     if message:
         log_and_show_message('{}: {}'.format(cls.get_displayed_name(), message))
         return False
     return True
Esempio n. 26
0
def start_window_config(window: sublime.Window, project_path: str,
                        config: ClientConfig, on_created: 'Callable'):
    args, env = get_window_env(window, config)
    config.binary_args = args
    session = create_session(
        config,
        project_path,
        env,
        settings,
        on_created=on_created,
        on_ended=lambda: on_session_ended(window, config.name))
    clients_by_window.setdefault(window.id(), {})[config.name] = session
    debug("{} client registered for window {}".format(config.name,
                                                      window.id()))
Esempio n. 27
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. 28
0
def show_input_panel(
    window: sublime.Window,
    caption: str,
    *,
    initial_text: str = "",
    on_done: "Callback[[str], None]" = None
) -> None:
    window.show_input_panel(
        caption=caption,
        initial_text=initial_text,
        on_done=on_done,
        on_change=None,
        on_cancel=None,
    )
Esempio n. 29
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. 30
0
def sublime_show_input_panel_async(
        window: sublime.Window, caption: str, initial_text: str,
        on_change: Callable[[str], None]) -> awaitable[Optional[str]]:
    result = main_loop.create_future()

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

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

    window.show_input_panel(caption, initial_text, on_done, on_change,
                            on_cancel)
    r = yield from result
    return r
Esempio n. 31
0
def log_server_message(window: sublime.Window, prefix: str,
                       message: str) -> None:
    window_id = window.id()
    if not window.is_valid(
    ) or window_id not in WindowPanelListener.server_log_map:
        return
    WindowPanelListener.server_log_map[window_id].append((prefix, message))
    list_len = len(WindowPanelListener.server_log_map[window_id])
    if list_len >= SERVER_PANEL_MAX_LINES:
        # Trim leading items in the list, leaving only the max allowed count.
        del WindowPanelListener.server_log_map[
            window_id][:list_len - SERVER_PANEL_MAX_LINES]
    panel = ensure_server_panel(window)
    if is_server_panel_open(window) and panel:
        update_server_panel(panel, window_id)
Esempio n. 32
0
def on_session_ended(window: sublime.Window, config_name: str):
    configs = window_configs(window)
    del configs[config_name]
    if not configs:
        debug("all clients unloaded")
        if clients_unloaded_handler:
            clients_unloaded_handler(window.id())
Esempio n. 33
0
def start_window_client(view: sublime.View, window: sublime.Window, config: ClientConfig):
    project_path = get_project_path(window)
    if project_path is None:
        debug('Cannot start without a project folder')
        return

    if can_start_config(window, config.name):
        if config.name in client_start_listeners:
            handler_startup_hook = client_start_listeners[config.name]
            if not handler_startup_hook(window):
                return

        if settings.show_status_messages:
            window.status_message("Starting " + config.name + "...")
        debug("starting in", project_path)
        start_window_config(window, project_path, config,
                            lambda session: handle_session_started(session, window, project_path, config))
    else:
        debug('Already starting on this window:', config.name)
Esempio n. 34
0
def create_references_panel(window: sublime.Window):
    panel = create_output_panel(window, "references")
    panel.settings().set("result_file_regex",
                         r"^\s+\S\s+(\S.+)\s+(\d+):?(\d+)$")
    panel.assign_syntax("Packages/" + PLUGIN_NAME +
                        "/Syntaxes/References.sublime-syntax")
    # Call create_output_panel a second time after assigning the above
    # settings, so that it'll be picked up as a result buffer
    # see: Packages/Default/exec.py#L228-L230
    panel = window.create_output_panel("references")
    return panel
Esempio n. 35
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. 36
0
def get_project_path(window: sublime.Window) -> 'Optional[str]':
    """
    Returns the common root of all open folders in the window
    """
    if len(window.folders()):
        folder_paths = window.folders()
        return folder_paths[0]
    else:
        view = window.active_view()
        if view:
            filename = view.file_name()
            if filename:
                project_path = os.path.dirname(filename)
                debug("Couldn't determine project directory since no folders are open!",
                      "Using", project_path, "as a fallback.")
                return project_path
            else:
                debug("Couldn't determine project directory since no folders are open",
                      "and the current file isn't saved on the disk.")
                return None
        else:
            debug("No view is active in current window")
            return None  # https://github.com/tomv564/LSP/issues/219
Esempio n. 37
0
def get_window_env(window: sublime.Window, config: ClientConfig):

    # Create a dictionary of Sublime Text variables
    variables = window.extract_variables()

    # Expand language server command line environment variables
    expanded_args = list(
        sublime.expand_variables(os.path.expanduser(arg), variables)
        for arg in config.binary_args
    )

    # Override OS environment variables
    env = os.environ.copy()
    for var, value in config.env.items():
        # Expand both ST and OS environment variables
        env[var] = os.path.expandvars(sublime.expand_variables(value, variables))

    return expanded_args, env
Esempio n. 38
0
def start_client(window: sublime.Window, project_path: str, config: ClientConfig):

    if config.name in client_start_listeners:
        handler_startup_hook = client_start_listeners[config.name]
        if not handler_startup_hook(window):
            return

    if settings.show_status_messages:
        window.status_message("Starting " + config.name + "...")
    debug("starting in", project_path)

    # Create a dictionary of Sublime Text variables
    variables = window.extract_variables()

    # Expand language server command line environment variables
    expanded_args = list(
        sublime.expand_variables(os.path.expanduser(arg), variables)
        for arg in config.binary_args
    )

    # Override OS environment variables
    env = os.environ.copy()
    for var, value in config.env.items():
        # Expand both ST and OS environment variables
        env[var] = os.path.expandvars(sublime.expand_variables(value, variables))

    # TODO: don't start process if tcp already up or command empty?
    process = start_server(expanded_args, project_path, env)
    if not process:
        window.status_message("Could not start " + config.name + ", disabling")
        debug("Could not start", config.binary_args, ", disabling")
        return None

    if config.tcp_port is not None:
        client = attach_tcp_client(config.tcp_port, process, settings)
    else:
        client = attach_stdio_client(process, settings)

    if not client:
        window.status_message("Could not connect to " + config.name + ", disabling")
        return None

    return client
Esempio n. 39
0
def get_document_state(window: sublime.Window, path: str) -> DocumentState:
    window_document_states = document_states.setdefault(window.id(), {})
    if path not in window_document_states:
        window_document_states[path] = DocumentState(path)
    return window_document_states[path]
Esempio n. 40
0
def get_project_config(window: sublime.Window) -> dict:
    project_data = window.project_data() or dict()
    project_settings = project_data.setdefault('settings', dict())
    project_code_intel_settings = project_settings.setdefault('SublimeCodeIntel', dict())
    return project_code_intel_settings
Esempio n. 41
0
def remove_window_client(window: sublime.Window, config_name: str):
    del clients_by_window[window.id()][config_name]
Esempio n. 42
0
def window_configs(window: sublime.Window) -> 'Dict[str, Session]':
    if window.id() in clients_by_window:
        return clients_by_window[window.id()]
    else:
        # debug("no configs found for window", window.id())
        return {}
Esempio n. 43
0
def restart_window_clients(window: sublime.Window):
    debug('Restarting clients for window {}'.format(window.id()))
    clear_document_states(window)
    restarting_window_ids.add(window.id())
    unload_window_sessions(window.id())
Esempio n. 44
0
def clear_document_states(window: sublime.Window):
    if window.id() in document_states:
        del document_states[window.id()]
Esempio n. 45
0
def ensure_references_panel(window: sublime.Window):
    return window.find_output_panel("references") or create_references_panel(window)
Esempio n. 46
0
def create_output_panel(window: sublime.Window, name: str) -> sublime.View:
    panel = window.create_output_panel(name)
    settings = panel.settings()
    for key, value in OUTPUT_PANEL_SETTINGS.items():
        settings.set(key, value)
    return panel
Esempio n. 47
0
def ensure_diagnostics_panel(window: sublime.Window):
    return window.find_output_panel("diagnostics") or create_diagnostics_panel(window)
Esempio n. 48
0
def clear_document_state(window: sublime.Window, path: str):
    window_id = window.id()
    if window_id in document_states:
        del document_states[window_id][path]
Esempio n. 49
0
def has_document_state(window: sublime.Window, path: str):
    window_id = window.id()
    if window_id not in document_states:
        return False
    return path in document_states[window_id]