fix(gdscript): address review feedback — configurable port/timeout, safer version detection

- Rename LSP_PORT → DEFAULT_GODOT_LS_PORT and add DEFAULT_GODOT_REQUEST_TIMEOUT
- Make port and request_timeout overridable via ls_specific_settings["gdscript"]
  by reading self._custom_settings in _create_language_server_interface
- Move self._conn_info setup into _create_language_server_interface so it can
  consume ls_specific_settings (which requires super().__init__ to have run)
- Fix _detect_godot_version to return int | None instead of always defaulting to 4:
  use an explicit config_version→major dict; return None for unrecognized versions
  and detection failures; caller logs warning on None
- Update setup guide and configuration reference docs with new settings

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Erik M JacobsandClaude Sonnet 4.6 committed 2026-05-13 10:03:46 -04:00
1 parent a1c281dc02
commit ef22522ee2
3 files changed
+63 -12

No files matched your search

+21
View File
@@ -487,6 +487,27 @@ Supported settings:
| `fsautocomplete_version` | `0.83.0` | Override the FsAutoComplete version Serena installs as a .NET tool. |
#### GDScript (Godot Engine)
Serena connects to the Godot editor's built-in LSP server over TCP. No separate process is launched.
Supported settings:
| Setting | Default | Description |
|---|---|---|
| `port` | `6008` | TCP port the running Godot editor listens on for LSP connections. |
| `request_timeout` | `30.0` | Seconds to wait for a response from the Godot LSP server. |
Example:
```yaml
ls_specific_settings:
gdscript:
port: 6008
request_timeout: 60.0
```
#### Go (`gopls`)
Serena forwards `ls_specific_settings.go.gopls_settings` to `gopls` as LSP `initializationOptions` when the Go language server is started.
@@ -19,9 +19,11 @@ When a Godot project is open in the editor, the editor listens for LSP connectio
Serena automatically detects which major version of Godot your project targets by reading the `config_version` field from `project.godot`:
- `config_version` ≥ 5 → Godot 4
- `config_version` = 5 → Godot 4
- `config_version` = 4 → Godot 3
If `config_version` is not recognized (e.g. from a future Godot release), Serena logs a warning and still connects — both Godot 3 and Godot 4 use the same port.
No additional configuration is needed for version detection.
---
@@ -71,6 +73,20 @@ To mitigate this:
| Editor must stay open | Serena requires the Godot editor to be running throughout the session. Closing the editor breaks the TCP connection; restart Serena after reopening the editor. |
| Slower workspace operations | `find_symbol` and `find_references` across the whole workspace are slower than for languages whose LSP servers support native workspace-wide queries. |
---
## Advanced Configuration
You can customize Serena's GDScript connection via `ls_specific_settings` in your `serena_config.yml` or `project.yml`:
```yaml
ls_specific_settings:
gdscript:
port: 6008 # TCP port the Godot editor listens on (default: 6008)
request_timeout: 30.0 # seconds to wait for an LSP response (default: 30.0)
```
These override the defaults only if explicitly set.
---
## Reference
@@ -20,10 +20,11 @@ from solidlsp.settings import SolidLSPSettings
log = logging.getLogger(__name__)
# config_version in project.godot: 5 → Godot 4, 4 → Godot 3
_GODOT4_CONFIG_VERSION = 5
# Maps config_version in project.godot to the Godot major version
_CONFIG_VERSION_TO_GODOT_MAJOR: dict[int, int] = {4: 3, 5: 4}
LSP_PORT = 6008
DEFAULT_GODOT_LS_PORT = 6008
DEFAULT_GODOT_REQUEST_TIMEOUT = 30.0
class GodotLanguageServer(SolidLanguageServer):
@@ -32,42 +33,55 @@ class GodotLanguageServer(SolidLanguageServer):
Both Godot 3 and Godot 4 expose an LSP server on TCP port 6008.
The Godot editor must already be running — this class connects to it
rather than launching it.
ls_specific_settings for ``gdscript``:
- ``port`` (int): TCP port the Godot editor's LSP listens on (default: 6008).
- ``request_timeout`` (float): seconds to wait for an LSP response (default: 30.0).
"""
def __init__(self, config: LanguageServerConfig, repository_root_path: str, solidlsp_settings: SolidLSPSettings) -> None:
self._godot_version = self._detect_godot_version(repository_root_path)
log.info("Detected Godot version %d for project at %s", self._godot_version, repository_root_path)
self._conn_info = TCPConnectionInfo(host="127.0.0.1", port=LSP_PORT)
if self._godot_version is not None:
log.info("Detected Godot version %d for project at %s", self._godot_version, repository_root_path)
else:
log.warning("Could not detect Godot version for project at %s", repository_root_path)
# Dummy ProcessLaunchInfo — _create_language_server_interface() ignores it
super().__init__(config, repository_root_path, ProcessLaunchInfo(cmd=""), "gdscript", solidlsp_settings)
@staticmethod
def _detect_godot_version(repo_path: str) -> int:
"""Read project.godot to determine the major Godot version. Defaults to 4."""
def _detect_godot_version(repo_path: str) -> int | None:
"""Read project.godot to determine the major Godot version.
Returns None if detection fails or the config_version is unrecognized.
"""
project_file = os.path.join(repo_path, "project.godot")
try:
with open(project_file, encoding="utf-8") as f:
for line in f:
line = line.strip()
if line.startswith("config_version="):
version = int(line.split("=", 1)[1])
return 4 if version >= _GODOT4_CONFIG_VERSION else 3
config_version = int(line.split("=", 1)[1])
return _CONFIG_VERSION_TO_GODOT_MAJOR.get(config_version)
except (FileNotFoundError, ValueError, OSError):
pass
return 4
return None
def _create_language_server_interface(
self,
process_launch_info: ProcessLaunchInfo,
logging_fn: Callable[[str, str, StringDict | str], None] | None,
) -> LanguageServerInterface:
settings: dict = self._custom_settings or {}
port = settings.get("port", DEFAULT_GODOT_LS_PORT)
request_timeout = settings.get("request_timeout", DEFAULT_GODOT_REQUEST_TIMEOUT)
self._conn_info = TCPConnectionInfo(host="127.0.0.1", port=port)
return TCPLanguageServer(
connection_info=self._conn_info,
language=self.language,
determine_log_level=self._determine_log_level,
logger=logging_fn,
request_timeout=30.0,
request_timeout=request_timeout,
)
@staticmethod