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

From: Michael Albinus <[email-masked]>
Date: Fri, 02 Dec 2022 17:14:01 +0100

Danny Freeman <[email-masked]> writes:

Hi Danny,

Sorry for being late, it took me a while to find a free time slot.

>> url-handlers.el supports already non-canonical schemes, see
>> `url-tramp-protocols'. We could add "jar" and "zipfile" to another user
>> option, `url-archive-protocols', and let tramp-archive.el do the job.
>
> I think this could be a nice thing to include in emacs itself.
> I have already implemented this funcitonality in a package on elpa:
> https://elpa.gnu.org/packages/jarchive.html if you want to look.

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

--8<---------------cut here---------------start------------->8---
          ((eq op 'abbreviate-file-name) uri)
          ((eq op 'make-auto-save-file-name) nil)
          ((eq op 'vc-registered) nil)
--8<---------------cut here---------------end--------------->8---

Eval prior your tests

--8<---------------cut here---------------start------------->8---
(trace-function 'jarchive--file-name-handler)
--8<---------------cut here---------------end--------------->8---

and you'll see what I mean in buffer *trace-output*.

>> Danny would, probably, but the recipe would involve a particular LSP server and clojure toolchain, i think.
>
> Indeed I do :)

I've prepared the test as indicated.

> Running `M-x eglot`
> Then `M-x xref-find-definitions` over the symbol `inc` should reproduce
> the error.

Well, running the test together with your package looks fine. What I
don't understand is the following sequence:

--8<---------------cut here---------------start------------->8---
[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))))
--8<---------------cut here---------------end--------------->8---

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?

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.