clojure-emacs / cider

The Clojure Interactive Development Environment that Rocks for Emacs

Home Page:https://cider.mx

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

cider-find-var on lib added via clojure.repl.deps/add-libs

filipesilva opened this issue · comments

Expected behavior

Using cider-find-var navigates to source of lib added with clojure.repl.deps/add-libs.

Actual behavior

Doesn't seem to find the source. cider-doc seems to work so the symbol seems to be loaded correctly.

Steps to reproduce the problem

;; needs clojure.core 1.12.0-alpha5
(require '[clojure.repl.deps :as deps])
(deps/add-libs {'org.clojure/data.csv {:mvn/version "1.1.0"}})
(require '[clojure.data.csv :as csv])

;; cider-find-var does not work, I guess because of the deps/add-libs
csv/read-csv

Environment & Version information

CIDER version information

;; CIDER 1.14.0-snapshot (package: 1.14.0-snapshot), nREPL 1.1.1
;; Clojure 1.12.0-alpha5, Java 21.0.2

Lein / Clojure CLI version

Clojure CLI version 1.11.1.1435

Emacs version

29.2

Operating system

Mac Sonoma 14.4.1

JDK distribution

openjdk 21.0.2 2024-01-16

commented

Interesting, we'd have to investigate. Should be a thin/easy fix.

Can you paste (meta #'csv/read-csv) here? Following the same prior steps

Thanks - V

Thanks for taking a look!

Here's the result of meta:

(meta #'csv/read-csv)
;; => {:arglists ([input & options]),
;;     :doc
;;     "Reads CSV-data from input (String or java.io.Reader) into a lazy\n  sequence of vectors.\n\n   Valid options are\n     :separator (default \\,)\n     :quote (default \\\")",
;;     :line 87,
;;     :column 1,
;;     :file "clojure/data/csv.clj",
;;     :name read-csv,
;;     :ns #namespace[clojure.data.csv]}
commented

Thanks! That looks right.

My actual question should have been:

What's the result of (clojure.java.io/resource "clojure/data/csv.clj")?

I noticed this a while ago too with the new sync-deps functionality in Clojure 1.12, the new libraries are added to the classpath but Cider couldn't find their source definition without a full REPL restart.

Looked into it a little and the issue appeared to be something to do with orchard.info/file-info which cider-nrepl's info middleware uses to transform the :file key - for some strange reason it exhibited different behaviour when called from a info op vs a regular eval op.
Might have something to do with interactive vs tooling sessions or thread-local vars?

commented

Could be anything. It might as well have to do with the classpath - probably Orchard's classpath matches 1:1 the JVM classpath at startup time, but newer Clojure features make it grow?

Let me know about (clojure.java.io/resource "clojure/data/csv.clj")

If my diagnostic is right, the fix could be potentially as simlpe as choosing one classloader over the other.

We might also ask around for best practices around classloader choice starting from Clojure 1.12.

Dug up my experiment log and ran it again using clojure.data.csv as the repro:

(ns repro)
(require '[clojure.repl.deps :as deps])
(deps/add-libs {'org.clojure/data.csv {:mvn/version "1.1.0"}})

(require '[clojure.data.csv :as csv])

(require '[clojure.java.io])
(clojure.java.io/resource "clojure/data/csv.clj")
;; => #object[java.net.URL 0x56797bbd "jar:file:/Users/yuhan/.m2/repository/org/clojure/data.csv/1.1.0/data.csv-1.1.0.jar!/clojure/data/csv.clj"]


(require '[orchard.info :as info])
(info/file-info "clojure/data/csv.clj")
;; => {:file
;;     #object[java.net.URL 0x56b9da93 "jar:file:/Users/yuhan/.m2/repository/org/clojure/data.csv/1.1.0/data.csv-1.1.0.jar!/clojure/data/csv.clj"],
;;     :resource "clojure/data/csv.clj"}

(require '[cider.nrepl.middleware.info :as c.info])
(-> (c.info/info-reply {:ns "repro"
                        :sym "csv/read-csv"})
    (select-keys ["file"]))
;; => {"file"
;;     "jar:file:/Users/yuhan/.m2/repository/org/clojure/data.csv/1.1.0/data.csv-1.1.0.jar!/clojure/data/csv.clj"}


;; but cider-find-var on this doesn't work:
csv/read-csv

From an elisp scratch buffer:

(with-current-buffer "repro.clj"
  (nrepl-dict-get
   (cider-var-info "inc")
   "file"))
;; =>
;; "jar:file:/Users/yuhan/.m2/repository/org/clojure/clojure/1.12.0-alpha8/clojure-1.12.0-alpha8.jar!/clojure/core.clj"

(with-current-buffer "repro.clj"
  (nrepl-dict-get
   (cider-var-info "csv/read-csv")
   "file"))
;; =>
;; "clojure/data/csv.clj"

(with-current-buffer "repro.clj" 
  (nrepl-dict-get  
   (cider-sync-tooling-eval
    "(:file (orchard.info/file-info \"clojure/data/csv.clj\"))"
    ;; "(:file (cider.nrepl.middleware.info/info-reply \"clojure/core/logic.clj\"))"
    )
   "value"))
;; =>
;; "#object[java.net.URL 0x7de93292 \"jar:file:/Users/yuhan/.m2/repository/org/clojure/data.csv/1.1.0/data.csv-1.1.0.jar!/clojure/data/csv.clj\"]"

At some point I used cider-debug to instrument orchard.info/file-info and found it was indeed returning different results depending on the context it was called from.. didn't have the time to investigate any further but I hope this helps with narrowing down the cause !

commented

Thanks! Seems a good starting point.