17 Commits
Author SHA1 Message Date
maxwang 4b726894d0 docs: correct configuration key names and typos 2026-09-21 13:24:58 +02:00
Dominik Jain 283140e7ae Refactor external language server registration
* Apply object-oriented design
* Establish common interface via protocol LanguageServerIdLike
* Move all registration concerns to LanguageServerRegistry
2026-09-12 15:15:34 +02:00
Merlin Hughes a9f99c679b Scala: wait for Metals' reported work, not a fixed 5 seconds (#1859)
Cross-file queries waited 5s after the first file was opened. On a cold Metals
that is long before it has imported the build, indexed, and — crucially —
compiled: references come from SemanticDB, which the build server writes as it
compiles, so a query made in between returns some of the references rather than
none, with nothing to mark it partial. Against a ~700-file Scala 3 build the
first find-references returned 124 of 242.

Metals already reports all of this as work-done progress; Serena did not declare
`window.workDoneProgress`, so none of it arrived. Declare it, track the tokens,
and wait for them before the first cross-file query — the same event-based shape
as TypeScript's indexing wait (#1639), whose hooks this uses.

Readiness is "nothing outstanding for a moment", not "nothing outstanding":
Metals hands off between its phases rather than overlapping them, so the token
set empties for around a second between the import ending and indexing starting,
and a plain drain returns in that gap. Measured on the same build, the first
find-references now returns all 242, taking 32s rather than 22s.
2026-08-13 11:43:24 +02:00
Merlin Hughes 8c1f3bcc98 Scala: give Metals the build roots rather than the repository root (#1767)
Metals serves one build per workspace folder, and Serena sends only the
repository root. Where the builds live below the root, Metals falls back to
its own search (BuildTools.searchForBuildTool), which looks one level down
and takes the *first* match — so in a monorepo every build but that one is
served with no build target, and cross-file references silently come back
empty.

Detect the build roots instead and send them all, one Metals service each.
`ls_specific_settings.scala.project_roots` names them explicitly where the
detection guesses wrong, `project_root_scan_depth` bounds the search.

The configured `ls_workspace_folders` are not usable for this: they are about
what SolidLSP indexes and are shared by every language server of a project, so
in a polyglot monorepo no single value suits both Metals and, say, tsserver.

Where the repository root is itself a build root, nothing changes.
2026-08-08 19:33:42 +02:00
Merlin Hughes 600d3b2fad Scala: answer Metals' build-import prompt (#1769)
* scala: answer Metals' build-import prompt

Metals asks, via window/showMessageRequest, whether to import a workspace it
has not seen before. Serena registered no handler, so the request came back
`method 'window/showMessageRequest' not handled on client` and Metals logged
"Unexpected error initializing server" and gave up. No build server, no build
target, and every cross-file query answered by the fallback presentation
compiler — which cannot see past the file it is given.

A client cannot decline the question instead: Metals' `disableShowMessageRequest`
is server-side configuration, and its no-op fallback answers "Not now", which
imports nothing either. Answering is the only route to a build.

So answer the three prompts that lead to a build server, and dismiss anything
else with `null` — a prompt we do not recognise is one whose consequences we
cannot judge, and two of Metals' others offer to kill a process and to open a
window. "Don't show again" is never chosen; Metals persists that in the
project's own state.

Since answering yes lets Metals run the project's build tool,
`ls_specific_settings.scala.auto_import_build: false` declines instead.

* scala: name the build-tool choice as a gap, and test the setting

`Messages.ChooseBuildTool` ("Multiple build definitions found. Which would
you like to use?") offers the build tools' own executable names, and precedes
the import prompt wherever a workspace holds more than one kind of build. It
is dismissed like anything else unrecognised, so such a workspace is still
not imported — a deliberate choice, since picking one is a guess of a
different order, but one the comment and the setup guide should admit to
rather than claim every prompt on the path is answered.

Also: cover the route from `ls_specific_settings` to `auto_import_build`,
which nothing exercised, and correct the `ImportBuildChanges` message in the
fixtures, which had the notification variant's trailing full stop rather than
the request's own text.
2026-08-08 16:28:04 +02:00
PETRO YAKOVYSHYN b7e7b86dd1 Unreal Engine: reorder the setup guide, fail on an empty compile_commands.json (#1610) 2026-06-28 12:59:29 +02:00
PETRO YAKOVYSHYN 3975a91bfe Add Unreal Engine 5 specific ignores, raises, docs and tests for C/C++ (#1564) 2026-06-25 11:23:25 +02:00
Erik M JacobsandClaude Sonnet 4.6 ef22522ee2 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>
2026-05-13 10:03:46 -04:00
Erik M JacobsandClaude Sonnet 4.6 1ab1c460cb feat: add GDScript (Godot Engine) language server support
Closes #1446. Adds Language.GDSCRIPT backed by a new TCPLanguageServer
that extends LanguageServerInterface directly — no intermediate transport
abstraction layer.

Changes:
- ls_process.py: adds TCPConnectionInfo dataclass and TCPLanguageServer,
  a LanguageServerInterface subclass that manages a TCP socket directly
  (mirroring how StdioLanguageServer manages a subprocess). Stop order
  closes the socket before the BufferedReader wrapper to avoid a deadlock
  where BufferedReader.close() blocks on its internal read lock while
  readline() holds it waiting for data.
- ls_config.py: adds Language.GDSCRIPT with .gd/.gdscript file matcher.
- language_servers/godot_language_server.py: GodotLanguageServer connects
  to the Godot editor's TCP LSP (port 6008, same for Godot 3 and 4),
  registers Godot-specific notification handlers, and performs the
  initialize/initialized handshake. Godot version is auto-detected from
  config_version in project.godot.
- docs: adds GDScript to the language support list and a dedicated setup
  guide covering prerequisites, setup steps, performance characteristics
  (no workspace/symbol support → first full scan is slow, disk cache
  persists across sessions), and known limitations.

Tested against Godot 4.6.1 on Linux (Fedora 41): TCP connection,
initialize handshake, textDocument/documentSymbol returning full symbol
tree, and clean shutdown in <1s.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 16:20:54 -04:00
Dominik Jain 25f5f5095f Adjust documentation to use uv tool installation as the main way of running things
* Add installation, update, etc.
* Remove use of `<serena>` and obsolete uvx examples.
2026-04-07 17:36:44 +02:00
Dominik Jain 6faf12b9fa Update uvx run instructions to include Python version (3.13)
uvx ignores not only the lock file but also the Python
version specified in pyproject.toml.
https://github.com/astral-sh/uv/issues/8206#issuecomment-4113536371
2026-04-02 13:25:58 +02:00
code4lala bf92f3cb49 feat: Support project-level ls_specific_settings (#1192) 2026-03-23 18:03:57 +01:00
John Haley 13e20c1cbd feat: Add comprehensive OCaml language support with ocaml-lsp-server integration (#573) 2026-03-04 21:56:49 +01:00
TJ Kolleh 1ea5f0c25f feat(scala): Add stale lock detection for Metals H2 database (#1012)
* feat(scala): Add stale lock detection for Metals H2 database

Add detection and automatic cleanup of stale Metals H2 database locks
to improve multi-instance support. When a Metals process crashes without
proper cleanup, it can leave a lock file that prevents proper AUTO_SERVER
coordination with new instances.

Changes:
- Add metals_db_utils.py with detection logic for stale locks
- Add StaleLockMode enum (auto-clean/warn/fail) for configurable behavior
- Add MetalsStaleLockError exception for fail mode
- Integrate stale lock checking into ScalaLanguageServer init
- Add configuration options: on_stale_lock, log_multi_instance_notice
- Add comprehensive unit tests for detection logic

This enhancement allows Serena's Metals to coexist with VS Code or other
editors running Metals on the same project, with proper handling of edge
cases like crashed processes.

* test(scala): Add integration tests for stale lock handling modes

Add 7 integration tests for ScalaLanguageServer stale lock detection:
- AUTO_CLEAN mode cleans stale locks and proceeds
- WARN mode logs warning without cleanup
- FAIL mode raises MetalsStaleLockError
- ACTIVE_INSTANCE logs info when notice enabled
- ACTIVE_INSTANCE silent when notice disabled
- NO_DATABASE proceeds silently
- NO_LOCK proceeds silently

Tests use mocking to avoid requiring Java/Coursier/Metals.

* docs(scala): Add multi-instance and stale lock documentation

Document Metals multi-instance support via H2 AUTO_SERVER:
- Explain how multiple Metals instances share database and Bloop
- Document memory considerations (~500MB per JVM)
- Add stale lock detection configuration options
- Document on_stale_lock modes (auto-clean, warn, fail)
- Add YAML configuration examples

* docs: Clean up docs

Removed memory considerations and additional configuration sections from the Scala setup guide.

* refactor(scala): Extract settings helper and add module-level constants

- Add DEFAULT_METALS_VERSION, DEFAULT_CLIENT_NAME, DEFAULT_ON_STALE_LOCK,
  DEFAULT_LOG_MULTI_INSTANCE_NOTICE constants to eliminate duplication
- Extract _get_scala_settings() pure function for centralized settings parsing
- Remove redundant cleanup_stale_lock import
- Add warning log when AUTO_CLEAN mode fails to remove stale lock
- Simplify lock path handling with ternary expression

This refactoring improves code maintainability by centralizing Scala
settings extraction and applying functional programming principles.

* chore(scala): fix typo in docstring and comments
2026-02-19 13:30:05 +01:00
Michael Panchenko e588bc7f89 C/C++ language server fixes (#987)
Fixes longstanding clangd issues (wrong selectionRange, failure to take compile_commands.json into account) and enhances documentation about C/C++ support
2026-02-06 15:25:43 +01:00
eez-eh 47bc4e0b32 Added partial Groovy language support (#833) 2025-12-16 15:11:46 +01:00
Dominik Jain faf3441ab2 Add content from README in docs structure 2025-11-07 18:00:00 +01:00