Skip to content

Gradle lsp#275

Open
tartarughina wants to merge 7 commits into
zed-extensions:mainfrom
tartarughina:gradle-lsp
Open

Gradle lsp#275
tartarughina wants to merge 7 commits into
zed-extensions:mainfrom
tartarughina:gradle-lsp

Conversation

@tartarughina

Copy link
Copy Markdown
Collaborator

Add Gradle Language Server support (gRPC-driven build model)

Summary

Adds Gradle build-file intelligence to the extension via Microsoft's Gradle Language Server, driven the same way the official VS Code Gradle extension drives it, by running the bundled gradle-server over gRPC. A new native binary, gradle-lsp-bridge, sits between Zed and the language server: it keeps a single gradle-server process (and its Gradle daemon) warm for the session, resolves the build model, and feeds it to the LS.

For Groovy .gradle scripts this gives plugin-aware completions (closures, plugin-contributed blocks like java {}/application {}), Maven Central dependency coordinates, and diagnostics. For Kotlin .gradle.kts scripts it provides syntax highlighting plus build-evaluation diagnostics (see below).

Kotlin DSL handling

The Gradle Language Server is Groovy-only (it can't parse Kotlin), so .gradle.kts doesn't get completions. But gradle-server itself runs Gradle's Kotlin-DSL compiler during configuration and emits real errors with file/line, the bridge captures these and surfaces them as editor diagnostics, which VS Code only logs. The Groovy LS's own (invalid) diagnostics for .gradle.kts are suppressed. Highlighting uses the bundled Kotlin grammar via a dedicated Gradle KTS language, scoped by longest-suffix-match so plain .kt files are unaffected.

Architecture / refactors included

  • proxy-common crate extracted: shared LSP framing + parent-process monitor + file:// URI helper, used by both native binaries (keeps the JDTLS proxy lean: no async/gRPC stack leaks into it).
  • gradle-lsp-bridge built as a separate binary (tokio/tonic/prost), so the gRPC dependency tree stays out of java-lsp-proxy.
  • Trait-based structure (Downloadable, LanguageServer) so the new server type and binary slot in cleanly; java.rs dispatch simplified.
  • Native binaries now share a single install directory via one constant (aligns with the direction in Rustify tasks #274).
  • Build-eval diagnostics merged with the LS's own diagnostics per URI (neither erases the other).

Configuration

Gradle settings live under the gradle-language-server LSP block (separate from jdtls). All optional works out of the box. Notably java_home controls the JDK the Gradle daemon uses (17+); it's configured per-server and falls back to $JAVA_HOME. Full reference in the README's new Gradle Build Files section.

Distribution

CI builds and ships gradle-lsp-bridge-<os>-<arch> assets alongside the proxy on the same release tag, across the existing 6-target matrix.

Testing

  • Unit tests for the bridge: save/injected-response detectors, diagnostics parsing (incl. the Kotlin-DSL failure shape), URI/framing helpers, and the model→executeCommand mapping.
  • Verified end-to-end against real Groovy and Kotlin-DSL projects: completions appear, build errors surface as squiggles with correct lines, and re-syncs after the daemon is warm are fast.
  • Builds + clippy clean on macOS/Linux/Windows targets and the wasm32-wasip1 extension target.

@cla-bot cla-bot Bot added the cla-signed label Jun 20, 2026
This commit introduces comprehensive Gradle build file intelligence to
the Zed Java extension:

- **gradle-lsp-bridge** (`gradle-bridge/`): A new native binary that
  bridges LSP (stdio) to the Microsoft Gradle Language Server (Unix
  socket / Windows named pipe) and drives the shipped
  `gradle-server.jar` over gRPC. This provides plugin-aware completions,
  closures, and build-script diagnostics. Build outcomes (successful
  models or evaluation errors) surface as diagnostics merged with the
  language server's syntax errors.

- **proxy-common**: Extracted shared primitives (LSP framing,
  parent-process monitor) into a new workspace crate, eliminating
  duplication between `java-lsp-proxy` and `gradle-lsp-bridge`.

- **gradle-sync workflow**: At server initialization and on every save
  of a Gradle build file or `gradle-wrapper.properties`, the bridge
  performs a `GetBuild` RPC to a long-lived, warm `gradle-server`
  process, coalescing bursts into a single pending rerun. The resulting
  model (plugins, closures, script classpaths) is forwarded to the
  language server via `workspace/executeCommand`, matching the VS Code
  extension's contract.

- **Groovy grammar**: Added `tree-sitter-groovy` to support `.gradle` /
  `.gradle.kts` syntax highlighting and queries.

- **GradleLs component**: Downloads the Gradle Language Server from the
  VS Code extension VSIX.

- **GradleBridge component**: Downloads the `gradle-lsp-bridge` binary
  as a per-platform asset alongside the JDTLS proxy.

- **Language registration**: `gradle` language (`.gradle` files) is now
  recognized and configured.
Move `parse_content_length`, `lsp_body`, and `contains_subslice` from
gradle-bridge into proxy-common's lsp module so both the proxy and
gradle-bridge can share the same LSP framing logic. Add comprehensive
unit tests covering edge cases and frame parsing.
Consolidate duplicate platform detection logic in `proxy.rs` and
`gradle_bridge.rs` into two shared helpers: `platform_exec_name` and
`platform_asset_name`. Both functions live in `util.rs` and handle
OS/arch mapping, file extensions, and `.exe` suffixes consistently.

Also remove explanatory comments from `gradle_ls_server.rs` that merely
restate the code.
Remove duplicate install path strings (`"proxy-bin"` and
`"gradle-bridge-bin"`) and replace with a shared `NATIVE_BIN_DIR`
constant set to `"bin"`. Both the proxy and Gradle bridge are versioned
together and can safely co-locate in the same directory.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant