-
Notifications
You must be signed in to change notification settings - Fork 202
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow path mapping for remote or Windows/WSL/Mingw servers #350
Comments
Can you pull up a concrete example of an LSP event exchange and show the before and after version that you would be able to pull off if you had the hooks you request? |
in the meantime, sounds like running Emacs in WSL might be a very quick way around this problem. Is there any restriction for doing this? |
@FelipeLema I think this issue "holds water", i.e. merits analysis, even if there is this workaround. |
Yes, primarily that you have to install and run a Windows X11 server (as well as install all the X client libs on the WSL side) and Windows X11 servers aren't very good and have various problems that make running Emacs that way fairly annoying. (Unless you just want to use terminal Emacs only, but that's also not ideal.) |
This may take me a while -- I did set up test language servers on WSL but didn't save the code once I saw it didn't work. I'll have to set that up again. Not all that hard, just a mental context switch or three ;-) |
someone else had a related problem which they solved at microsoft/WSL#3907 (comment) I'm pointing this out because it seems the user was very flustered about this issue and, from the looks of the solution being presented, there's no way around it here in eglot other than adding |
there's a |
Yes, wslpath is part of WSL (it's included in Microsoft's Ubuntu distro for instance). I know, you kind of "just have to know" this stuff. :-(
and check e.g. https://docs.microsoft.com/en-us/windows/wsl/interop This week I am trying to build emacs on WSL and run an X server to see if that improves my situation with eglot. No results yet but I'll let you know. I would think that since eglot can connect to a remote LSP process (via host/port), it, or maybe the protocol itself, would need some path-mapping anyway, right? Presumably there's no guarantee that the local filesystem is mounted the same way as the remote (where the lsp server is running), even in an all-Linux environment. Or maybe this hasn't been thought through yet? |
oh, I got confused along the way tramp support can help you if you edit your files remotely using something like Worth noting that using a Virtualbox with a guest Linux machine + mounting vbox shares would be much easier than compiling emacs with X in WSL. I'm using this setup at work for the same reasons, although I'm editing remote files through ssh. You can try this setup while we wait for #463 as it looks like the best candidate solution so far to this issue. |
I have the following setup, which I think ends up imposing the same requirements as @garyo described in the intro to this ticket: basically eglot needs a hook to make an arbitrary transformation to a file path. The setup:
Note that
So the typical situation is that the host Emacs process is visiting a file on the host OS, not using Tramp, but we want eglot to be able to jump to the definition of something in 3rd-party code. This requires eglot to translate the file path received from the server into a docker-tramp style file path. But unlike #463 it cannot use I needed something quick to be able to work, so for what it's worth here's what I'm currently using. (This is just a quick hack but I'm happy to help out with making the proper changes to eglot to do the various things being requested regarding tramp and remote paths.) Change to eglot commit 48566594aeef5718aaa17ff9625672b0ad5af8c6
Author: Dan Davison <[email protected]>
Date: Fri Apr 24 20:07:57 2020 -0400
Add user variable eglot-transform-path-function
diff --git a/eglot.el b/eglot.el
index 8dae0b7..51d0524 100644
--- a/eglot.el
+++ b/eglot.el
@@ -203,6 +203,16 @@ let the buffer grow forever."
:type '(choice (const :tag "Don't show confirmation prompt" nil)
(symbol :tag "Show confirmation prompt" 'confirm)))
+(defcustom eglot-transform-path-function #'identity
+ "A function to transform a file path received from the server into the
+appropriate path for the client.
+
+This can be used when the server and the client do not share the
+same filesystem, for example to transform the path received from
+the server into a tramp-style path which the client can use to
+read and write the remote file."
+ :type 'function)
+
;;; Constants
;;;
@@ -1886,7 +1896,7 @@ Calls REPORT-FN maybe if server publishes diagnostics in time."
"Like `xref-make-match' but with LSP's NAME, URI and RANGE.
Try to visit the target file for a richer summary line."
(pcase-let*
- ((file (eglot--uri-to-path uri))
+ ((file (funcall eglot-transform-path-function (eglot--uri-to-path uri)))
(visiting (or (find-buffer-visiting file)
(gethash uri eglot--temp-location-buffers)))
(collect (lambda () My personal config: (defun dan/eglot-pyls-transform-path-to-docker-tramp (path)
(cl-destructuring-bind (container-id)
(cl-loop for (id name) in (docker-tramp--running-containers)
if (s-contains-p "_pyls_" name)
collect id)
(format "/docker:%s:%s" container-id path)))
(setq eglot-transform-path-function #'dan/eglot-pyls-transform-path-to-docker-tramp) |
What I suggest is:
If anyone has any doubts about the appropriateness/necessity of this, or about that style of solution, then that would be helpful to know. I hope my description above didn't seem too complex/niche -- it's a common situation with docker-based workflows. In fact, it was the difficulty of solving that without LSP that brought me to eglot. |
I think the mapper has to work both ways, btw -- Emacs needs to be able to tell the server where to find the file, and to interpret paths/URIs coming from the server. At least that's my understanding. |
Yes, good point, agreed. (My code example was just the minimum necessary that got one thing working with my particular setup -- jump-to-definition of something that is defined in a file that is accessible to the server process but not on the same filesystem as Emacs.) |
Yes exactly. In SLIMM or SLY (two Common Lisp IDE's with a lot in common with LSP), it's done via a variable. Have a look here: https://github.com/joaotavora/sly/blob/master/contrib/sly-tramp.el |
I'm having exactly the same setup as dandavison - i.e. my own code is on the host machine, and dependencies are in the container. I wonder if anything changed throughout the years that made a setup like this conveniently possible. Sorry if it's better to not continue discussion in already open issues and it's better to move them to emacs-devel |
after all these years I can only suggest using Tramp as a last resource: works great if you leave it untouched, but customizing and debugging is a lot of work (and probably not worth the effort). Try mounting paths from the container in the host machine so Emacs can see them. |
Also, after 4 years, I have to admit I don't understand what the problem is about anymore. I have to re-read the comments. I'm tempted to say that TRAMP support (which didn't exist back in 2019) is a good fix for this, but I have to re-learn the problem. |
I run Emacs on Windows, but all the rest of my development environment is in Linux using WSL on the same machine. So it's not remote as such, but each side has its own path prefixes. Right now I'm installing the language server on the Windows side just so eglot and intellisense will work; I'd love to use the Linux-side language server, but there's a filename translation problem. Windows
c:/foo/bar
becomes/mnt/c/foo/bar
in Linux (with default mappings anyway). If in the work you're doing here, you could allow for a filename-mapping hook (i.e. between Emacs's idea of filename and the server's idea), so I could use the Linux language server, people in my situation would be very grateful! (Note that it's no problem for Windows Emacs to start a Linux process using WSL, and get its stdio and so on. It's just the filename mapping at issue.)The same issue happens between Windows and Mingw/Msys/Cygwin by the way; you need a simple form of pathname translation.
I suggest adding a couple of pathname-translation hooks for client-to-server and server-to-client pathname mapping.
See #348.
The text was updated successfully, but these errors were encountered: