clojure-emacs / clojure-emacs/cider

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

Open
#4,040 0 comments 0 reactions 0 assignees View on GitHub
enhancement
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.