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

From: Michael Albinus <[email-masked]>
Date: Fri, 09 Dec 2022 17:04:25 +0100

Danny Freeman <[email-masked]> writes:

Hi Danny,

>> The LSP server shouldn't care. It returns a local file name, like
>> "jar:file:///home/albinus/.m2/repository/org/clojure/clojure/1.10.3/clojure-1.10.3.jar!/clojure/core.clj". This
>> is because the file is local from the server's pov.
>
>> It is the client, Eglot, which must be able to access this file on the
>> remote machine. A task for your jarchive file name handler, I believe.
>>
>> Or do I misunderstand the architecture?
>
> I think I am just confused at this point. Can you explain more about
> what your current setup is for this question? In trying to understand,
> it sounds like you are using Emacs to connect to a remote machine
> somewhere via tramp. On the remote machine is a clojure project and a
> running clojure-lsp server. When you try to navigate to a definition in
> a jar, it is returning a jar URI pointing to something on your local
> machine, not the remote machine like it should? Does that sound right?

Yes, this is what it looks like. I don't believe it is an error in the
LSP server.

The eglot architecture, AFAIU, runs always the the LSP server on the
same machine as the file under investigation is located on. For local
files it is obvious: in eglot--connect, make-process is called, which
connects to the LSP server on the local machine.

If you have a remote file, say
/ssh:user@host:/usr/local/src/emacs/src/dbusbind.c (in order to use a
more simple LSP server like clangd), they same happens: make-process is
called. *But* make-process realizes that default-directory is a remote
one (/ssh:user@host:/usr/local/src/emacs/src//), and so it calls clangd
on that remote host.

That LSP server doesn't care where the client is called from. It still
does

--8<---------------cut here---------------start------------->8---
[client-request] (id:20) Fri Dec  9 16:47:05 2022:
(:jsonrpc "2.0" :id 20 :method "textDocument/definition" :params
	  (:textDocument
	   (:uri "file:///usr/local/src/emacs/src/dbusbind.c")
	   :position
	   (:line 171 :character 0)))
[server-reply] (id:20) Fri Dec  9 16:47:05 2022:
(:id 20 :jsonrpc "2.0" :result
     [(:range
       (:end
	(:character 22 :line 172)
	:start
	(:character 0 :line 172))
       :uri "file:///usr/local/src/emacs/src/dbusbind.c")])
--8<---------------cut here---------------end--------------->8---

So the client requests to get a definition in (the server local) file
"file:///usr/local/src/emacs/src/dbusbind.c" at a given position, and
the server replies with a pointer to the (server local) file
"file:///usr/local/src/emacs/src/dbusbind.c". It is up to the client
(eglot), to translate this information into remote file name syntax
"/ssh:user@host:/usr/local/src/emacs/src/dbusbind.c".

> Fwiw, I have never used tramp before, so I'm not sure how Eglot or
> clojure-lsp will behave in that kind of environment.

I suppose for clojure the same spplies. If the LSP server on that remote
host returns something like a (server local) file
"jar:file:///home/albinus/.m2/repository/org/clojure/clojure/1.10.3/clojure-1.10.3.jar!/clojure/core.clj",
it is up to the (eglot) client to recognize this as a pointer to the
remote file at the given location. This problem is not tackled yet by
your jarchive package.

Best regards, Michael.