Subject: bug#58790: Eglot URI parsing bug when using clojure-lsp server

From: Danny Freeman <[email-masked]>
Date: Wed, 07 Dec 2022 13:56:37 -0500

Michael Albinus <[email-masked]> writes:

> Danny Freeman <[email-masked]> writes:
>
> Hi Danny,
>
> Sorry for being late, it took me a while to find a free time slot.
>

No worries, we are all busy! I understand.

> Well, the jar: and zipfile: semantics is a little bit different from
> what url-handlers supports. So let's continue with your package ATM; we
> could replace it by an implementation in url-handlers later on if we
> like.
>
> I gave your package a short review, it looks nice. Testing it together
> with eglot and the recipe below works nicely. Just one recommendation: I
> would add in jarchive--file-name-handler
>
>           ((eq op 'abbreviate-file-name) uri)
>           ((eq op 'make-auto-save-file-name) nil)
>           ((eq op 'vc-registered) nil)
>
>
> Eval prior your tests
>
> (trace-function 'jarchive--file-name-handler)
>
>
> and you'll see what I mean in buffer *trace-output*.

I do see that, I'll be publishing a change that includes this later
today. I'll have to remember to use trace-function more often. What a
nifty tool!

>
> Well, running the test together with your package looks fine. What I
> don't understand is the following sequence:
>
> [client-request] (id:6) Fri Dec  2 17:04:01 2022:
> (:jsonrpc "2.0" :id 6 :method "textDocument/definition" :params
> 	  (:textDocument
> 	   (:uri "file:///usr/local/src/eglot-xref-to-jar-repo/src/user.clj")
> 	   :position
> 	   (:line 3 :character 3)))
> [server-reply] (id:6) Fri Dec  2 17:04:01 2022:
> (:jsonrpc "2.0" :id 6 :result
> 	  (:uri "jar:file:///home/albinus/.m2/repository/org/clojure/clojure/1.10.3/clojure-1.10.3.jar!/clojure/core.clj" :range
> 		(:start
> 		 (:line 923 :character 6)
> 		 :end
> 		 (:line 923 :character 9))))
>
> That means, that the client (my local Emacs) has asked for
> "textDocument/definition" on the file user.clj, as indicated by your
> recipe. The remote server has returned as answer, that this definition is in
> "jar:file:///home/albinus/.m2/repository/org/clojure/clojure/1.10.3/clojure-1.10.3.jar!/clojure/core.clj". This
> file must be located on the server, because the server cannot know
> anything about my local configuration, right?

The server should be running on your machine locally, and have access to
everything Emacs does. It knows the location of that jar because it uses
the clojure build tool to create a classpath for the project, which
contains the full location of the clojure-1.10.3.jar file.

>From what the clojure-lsp maintainers tell me, it will not run on a
remote machine and be able to work with a project on your local machine.
I'm not sure what it would return for a definition if it was able to run
on a remote machine.

> But your jarchive package opens this file locally. It works, because on
> my local machine I have the same file, but it looks confusing to
> me. What if the file doesn't exist locally?
> Best regards, Michael.

I did some testing with this and it depends. Clojure-lsp needs the jar
dependencies to do it's analysis, so it will use whatever clojure build
tool the project uses to download them on startup if they do not exist
(given that it is listed as a dependency in the project file, deps.edn
in the case of my recipe).

If it doesn't exist locally after clojure-lsp has started then it will
return the same jar path, but opening the jar file will of course fail.
If this happens it's because the user or some other process deleted the
jar. There isn't much to be done about that.

-- 
Danny Freeman