diff --git a/src/solidlsp/language_servers/godot_language_server.py b/src/solidlsp/language_servers/godot_language_server.py index d0ea8c3f..fe3df8b5 100644 --- a/src/solidlsp/language_servers/godot_language_server.py +++ b/src/solidlsp/language_servers/godot_language_server.py @@ -13,7 +13,7 @@ from collections.abc import Callable from solidlsp.ls import SolidLanguageServer from solidlsp.ls_config import LanguageServerConfig from solidlsp.ls_process import LanguageServerInterface, TCPConnectionInfo, TCPLanguageServer -from solidlsp.lsp_protocol_handler.server import ProcessLaunchInfo, StringDict +from solidlsp.lsp_protocol_handler.server import StringDict from solidlsp.settings import SolidLSPSettings log = logging.getLogger(__name__) @@ -47,7 +47,7 @@ class GodotLanguageServer(SolidLanguageServer): self._configured_request_timeout: float | None = None # Dummy ProcessLaunchInfo — _create_language_server_interface() ignores it - super().__init__(config, repository_root_path, ProcessLaunchInfo(cmd=""), "gdscript", solidlsp_settings) + super().__init__(config, repository_root_path, None, "gdscript", solidlsp_settings) def set_request_timeout(self, timeout: float | None) -> None: """Cap the timeout at the value configured in ls_specific_settings, if set.""" @@ -73,11 +73,7 @@ class GodotLanguageServer(SolidLanguageServer): pass return None - def _create_language_server_interface( - self, - process_launch_info: ProcessLaunchInfo, - logging_fn: Callable[[str, str, StringDict | str], None] | None, - ) -> LanguageServerInterface: + def _create_language_server_interface(self, logging_fn: Callable[[str, str, StringDict | str], None] | None) -> LanguageServerInterface: settings = self._custom_settings or {} port = settings.get("port", DEFAULT_GODOT_LS_PORT) request_timeout = settings.get("request_timeout", DEFAULT_GODOT_REQUEST_TIMEOUT) diff --git a/src/solidlsp/ls.py b/src/solidlsp/ls.py index 8731204d..82ac0c30 100644 --- a/src/solidlsp/ls.py +++ b/src/solidlsp/ls.py @@ -511,14 +511,10 @@ class SolidLanguageServer(ABC): else: logging_fn = None - # create the LanguageServerHandler, which provides the functionality to start the language server and communicate with it, - # preparing the launch command beforehand + # create the low-level server interface, potentially installing dependencies and launching a subprocess + self._process_launch_info: ProcessLaunchInfo | None = process_launch_info self._dependency_provider: LanguageServerDependencyProvider | None = None - if process_launch_info is None: - self._dependency_provider = self._create_dependency_provider() - process_launch_info = self._create_process_launch_info() - log.debug(f"Creating language server instance with {language_id=} and process launch info: {process_launch_info}") - self.server = self._create_language_server_interface(process_launch_info, logging_fn) + self.server = self._create_language_server_interface(logging_fn) """ the low-level language server interface """ @@ -564,15 +560,23 @@ class SolidLanguageServer(ABC): f"{self.__class__.__name__} must implement _create_dependency_provider() or pass process_launch_info to __init__()" ) + def _get_dependency_provider(self) -> LanguageServerDependencyProvider: + if self._dependency_provider is None: + self._dependency_provider = self._create_dependency_provider() + return self._dependency_provider + def _create_process_launch_info(self) -> ProcessLaunchInfo: - assert self._dependency_provider is not None - cmd = self._dependency_provider.create_launch_command() - env = self._dependency_provider.create_launch_command_env() + dependency_provider = self._get_dependency_provider() + cmd = dependency_provider.create_launch_command() + env = dependency_provider.create_launch_command_env() return ProcessLaunchInfo(cmd=cmd, cwd=self.repository_root_path, env=env) - def _create_language_server_interface( - self, process_launch_info: ProcessLaunchInfo, logging_fn: Callable[[str, str, StringDict | str], None] | None - ) -> LanguageServerInterface: + def _get_process_launch_info(self) -> ProcessLaunchInfo: + if self._process_launch_info is None: + self._process_launch_info = self._create_process_launch_info() + return self._process_launch_info + + def _create_language_server_interface(self, logging_fn: Callable[[str, str, StringDict | str], None] | None) -> LanguageServerInterface: """ Creates the low-level language server interface for LSP communication. @@ -581,10 +585,12 @@ class SolidLanguageServer(ABC): The default implementation creates a StdioLanguageServer, but subclasses can override this method to create a different type of interface if needed. - :param process_launch_info: process launch information :param logging_fn: the trace logging function :return: the interface """ + language_id = self.language_id + process_launch_info = self._get_process_launch_info() + log.debug(f"Creating language server instance with {language_id=} and {process_launch_info}") return StdioLanguageServer( process_launch_info, language=self.language,