Skip to content

Fetch jar/resource source over nREPL instead of via the filesystem #4040

Description

@bbatsov

Jumping to a definition that lives inside a jar currently works by resolving the jar on a filesystem. For remote setups (TRAMP/SSH, Docker) that path is fragile and slow, and it's the root of the recurring remote-navigation friction.

How it works today

cider-find-file parses jar:file:/...!/ns/foo.clj and, for a remote jar, pulls the whole jar over TRAMP into an arc-mode buffer, then re-search-forwards for the entry and archive-extracts it. Locally it shells out to unzip. The remote branch has a few problems:

  • it transfers the entire jar over the wire just to read one file (the "Emacs hangs on a big jar" symptom);
  • the entry search depends on the archive listing being fully decoded first, which is timing- and coding-sensitive - this is what bit Cider cannot open Jar files by SSHx/Tramp #3409 (a global coding-system-for-read override corrupted the binary read; not actually a TRAMP limitation, but it shows how brittle the path is). The local branch binds coding-system-for-read defensively; the TRAMP branch doesn't;
  • tramp-archive isn't a portable rescue: it needs GVFS (Linux/GNOME only) and a GVFS method, so it does nothing for macOS/Windows + plain ssh/sshx.

On top of that, cider-path-translations only helps when an equivalent file already exists on the local host (see #2091), and its dir-local value is lost once you land in a jar buffer (worked around today by cider--all-path-translations scanning every buffer).

Proposal

Let the side that owns the classpath read the bytes: add a cider-nrepl op (something like resource-contents/ns-contents) that slurps the resource and returns the decoded text, and have CIDER render it in a synthesized read-only buffer.

This would make jar/resource navigation work uniformly regardless of OS, TRAMP method, GVFS availability, or whether the jar exists on the host - transferring one file instead of the whole jar, and removing the need for cider-path-translations for this case entirely.

There's precedent in the same direction: cider-download-java-sources already has the server hand source text back to the client (#3817, default since 1.17).

Trade-off

The resulting buffer is a virtual read-only copy, not a real file path, so xref/back-navigation and anything keyed on buffer-file-name need a small virtual-file convention. That's the main design question to settle.

Needs a companion change in cider-nrepl for the op. Related: #2091, #3409, #2148.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions