clojure-emacs / clojure-emacs/cider
Fetch jar/resource source over nREPL instead of via the filesystem
- Dominant language
- Emacs Lisp
- Stars
- 3.7k
- Forks
- 651
- Avg merge
- 11h 6m
- Merged PRs (30d)
- 33
Description
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-forward`s for the entry and `archive-extract`s 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 #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 `slurp`s 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.
Contributor guide
Research direction
Start with cider-find-file and the existing cider-download-java-sources path, then inspect cider-path-translations and cider--all-path-translations for assumptions about real files. Coordinate the companion cider-nrepl change and settle the virtual-file convention; done means resource contents arrive over nREPL and render in a read-only buffer without requiring the jar locally or transferring the whole archive.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- clojure, emacs-lisp
- Domain
- backend-api-design, developer-experience, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100