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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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