reddit / emacs

Running LSP over Tramp — why?

astoff1 · 2022-09-30 09:32
Running Eglot or lsp-mode while working on remote files seems to be a common and rather problematic use-case, so I'm trying to understand why so many people need this. I have several projects where I can't or am not allowed to execute any code locally, and instead have a remote machine available for computations. But I've never encountered a project were I can't have the source code itself locally. So what I do is to edit the code locally and periodically sync it with the remote machine. The syncing part is admittedly a bit awkward, but there are ways to make it easier or mostly automatic. And then all Emacs features and external tools work fast and smoothly.
sunnyata · 2022-09-30 10:14
I used to do this sort of thing when I worked on back end stuff where it just wasn't feasible to recreate the test environment locally. It was a long time ago and I must admit I didn't know anything about mocking.
JoshuaOC · 2022-09-30 10:58
> But I've never encountered a project were I can't have the source code itself locally. There are other points to be made, but the simplest one is: These projects do exist (I'm on one) :). Even if someone can have the literal source code, if they want LSP/testing/linting, they do have to maintain some environment on their local machine, this environment can get out of sync with what is actually used, which can become a headache (hence the impetus to remote dev environments). In my experience, TRAMP + LSP is tolerable (but far worse than local) if the latency to the remote environment is <20ms. Above that and it's just too dang bad for me at least. Those cases, which unfortunately I've been in, are where VSCode's architecture with the separate process on the remote host fairs much better.
soumya6097 · 2022-09-30 11:19
Okay let me answer you why. 1. I have many projects on multiple GPU-servers with their own anaconda environments. I want the autocomplete to be environment aware while editing files from corresponding projects. If I do locally, then I have to replicate all those environments. If I install something on fly then I have to do it locally too. do you see the problem now? 2. Many packages are also difficult to install and its not suitable to make copy here and there all the time. 3. As you said, doing locally and transferring to remote is awkward. We have a successful model like vscode so why not in emacs? Tramp makes the pipeline easier and lsp needs to work there.
soumya6097 · 2022-09-30 11:21
Missed your comment and wrote the same points as you.
7890yuiop · 2022-09-30 12:16
If your development environments are not at least approximations of the associated production environments, I would suggest that you are doing "development environments" wrong. Either that, or you don't work on the kinds of projects that many people work on. For me that means my development environments are either virtual machines or sets of dockers containers, and it's not always trivial to have Emacs running inside those -- but it *is* trivial (and still pretty fast) to have Emacs accessing those locally-hosted environments via tramp. If I can easily run Emacs inside my dev environment, then I do so. If I cannot, then tramp is excellent. (And as far as LSP goes, Eglot works fine over tramp, so I haven't found this to be a "rather problematic use-case".) > what I do is to edit the code locally and periodically sync it with the remote machine. Isn't it funny how different workarounds will sound absolutely awful to different people, depending on whether or not they're personally used to using them? :)
sammymammy2 · 2022-09-30 12:27
1 million source lines. Laptop at home has like 16GB of RAM and 4 coures, work computer has 128GB of RAM and 32 cores. Guess which one I'd rather have indexing and building against :)? I gave up on that use case though, because the ping is 70ms between my work computer and laptop...
astoff1 · 2022-09-30 12:48
>> what I do is to edit the code locally and periodically sync it with the remote machine. > Isn't it funny how different workarounds will sound absolutely awful to different people, depending on whether or not they're personally used to using them? :) So you don't use REPLs, right? Because if I edit some Python source code that is imported in a notebook or suchlike, I have to somehow sync up the Python interpreter with this new code, which is pretty much the same kind of issue.
astoff1 · 2022-09-30 12:53
> this [local] environment can get out of sync with what is actually used If you are using a CI or any other kind of automated deployment, then you need an automated way to obtain an up-to-date linting/testing environment anyway, right?
astoff1 · 2022-09-30 12:55
Emacs has more than 1 million LOC and I can run grep just fine. Building, training, or whatever else is compute-intensive is better done remotely, of course.
astoff1 · 2022-09-30 12:59
> If your development environments are not at least approximations of the associated production environments, I would suggest that you are doing "development environments" wrong. Not sure how this related to the remote vs. local question. My development environment has exactly the same interpreter and packages as the production environment, installed locally. In Python you only need a venv to achieve this. In other languages, putting everything inside a container *might* be easier, I don't know.
astoff1 · 2022-09-30 13:00
>We have a successful model like vscode so why not in emacs This is more or less equivalent to running Emacs in an ssh terminal, right? Or, perhaps better, inside mosh.
HeyItsLP · 2022-09-30 13:08
Other commenters all made good points, but i wanted to share my use cases. Code which is under NDA and is not allowed to be stored in personal machines. Working inside of Docker containers for projects, whose dependencies I do not wish to bring in to my local system, this is especially prevalent when multiple versions of something are in play (older versions of Java or LLVM). For environmental awareness. I have some Linux kernel modules I contribute to, but I do most of my development from my laptop, which is an M2 macbook air. I have a home server with the hardware I'm targeting which I TRAMP over to and have access to libraries and headers I simply cannot test locally. Additionally this lets me debug software which is cross built (previously mentioned Linux specific projects).
soumya6097 · 2022-09-30 13:26
It is in a way yes. Then again I need to manage multiple terminals (+all the GUI things gone for me). If you use WSL and windows terminal then best of luck. There are many workarounds but tramp way is the most convenient one (I feel at least). May be this is the reason for the tramp to exist.
7890yuiop · 2022-09-30 13:44
I make heavy use of REPLs. The processes are, of course, running inside my development environments, with Emacs (whether local or remote) talking to that process. Furthermore the inferior processes for some REPLs need to have access to the whole environment (all services); so in those cases it couldn't be any other way.
7890yuiop · 2022-09-30 13:46
Hence the part that you didn't quote^1 : > > Either that, or you don't work on the kinds of projects that many people work on. I.e. A great many projects involve clusters of multiple different kinds of services, implemented in arbitrary languages, all working together. ---- ^1 It might not have been there to quote -- I'd added that caveat a little after the initial comment.
sirsamsai · 2022-09-30 13:49
Sometimes I work on a project that requires vastly more compute power than my work laptop has. For example, projects that require frequent or heavy compiling or projects that execute one-off processes that take a long time over the weekend. Sometimes I work on services that require specific network connectivity to test them, and I don't want to rsync my files over and then spend time separately figuring out why it doesn't work. For example, prototyping services that interact with other services via callback requests. Sometimes I work on technology stacks that are messy and I want to contain them inside project-specific containers, so as to avoid having a bunch of files outside of package manager control sitting in random places of my system. It's more palatable if some tech requires me to run "curl | bash" if I know I can at least wipe the environment easily afterwards. Since I also use Fedora Silverblue at home, running my development environments inside containers and connecting to those containers via Tramp is a simple approach that lets me use multiple containers from a single Emacs instance.
astoff1 · 2022-09-30 15:15
> Sometimes I work on a project that requires vastly more compute power than my work laptop has. Right, same here. But, as I pointed out in the OP, none of this forces you to edit remote files. > Sometimes I work on services that require specific network connectivity to test them, and I don't want to rsync my files over and then spend time separately figuring out why it doesn't work. Okay, but what do you do after you figured out why it doesn't work? You've got to rsync or otherwise send the good code somewhere.
astoff1 · 2022-09-30 15:26
I do exactly the same. My point was, I can't compile code or run some unit tests correctly before syncing up my Emacs buffer contents with the files on disk (you know, the good old `C-x C-s`), and likewise I can't run some new code in the remote REPL without first syncing up my local files with the remote ones. Maybe you're right that this syncing stuff is _absolutely awful_, but everybody does it all the time.
servingwater · 2022-09-30 15:47
Developing over Tramp was never a pleasant experience for me. Not sure how people do it. Their setup must tweaked really good. Mine was always pretty much out of the box. Tramp/LSP/Projectile and Tramp always started crawling and be pretty much unusable. Installing emacs remotely and using in there was the best workaround for me. But it's true that to some that might not aleways be an option. I considered Tramp always as something to only edit some files here and there but as a remote dev environment it was (is?) severely lacking. Vscode's remote plugin has that one down the best IMHO.
[deleted] · 2022-09-30 16:36
[removed]
ttmp3 · 2022-09-30 18:00
> Emacs has more than 1 million LOC and I can run grep just fine. Building, training, or whatever else is compute-intensive is better done remotely, of course. Editing code is much more than running grep though. When developing C++, a change in a header file may trigger reindexing of a large part of project, which could be very resource-intensive.
paretoOptimalDev · 2022-09-30 18:24
A lot of projects are starting to provide \[vscode devcontainers\]([https://code.visualstudio.com/docs/remote/create-dev-container](https://code.visualstudio.com/docs/remote/create-dev-container)) which are docker containers that sometimes have some extra setup. An emacs user has three options I know of if their team defaults to one of those: \- do their own thing and setup things locally and maintaining that setup \- Use eglot+tramp to develop closer to the model the rest of the team uses \- Use the devcontainer as a base and expose a volume, and write wrapper scripts. Docker volumes can be slow in some cases, such as when used from an M1 mac. Yes even with the experiment virtIO feature that sometimes breaks. I tried going with the last option for a Haskell project at work for a while, but the slowdown was 1m30s compile time vs 20s compile time and just not worth it. Also I had to make sure to disable ansi and other things in the wrapper scripts to not break emacs integrations. I now work from within the devcontainer similar to how vscode users would using eglot and tramp. There's a bit of noticeable latency when saving files, but it's a much better development experience.
paretoOptimalDev · 2022-09-30 18:26
>Those cases, which unfortunately I've been in, are where VSCode's architecture with the separate process on the remote host fairs much better. One advantage tramp+lsp have here is they use no resources. The VSCode server routinely uses 5-30% CPU in devcontainers I've noticed when I'd expect it to be idle. Even so I can imagine the remote latency making vscodes model nicer and wish you could do the same by remotely connecting to an emacs server.
paretoOptimalDev · 2022-09-30 18:27
It's like the reverse. It's like gui emacs but everything is processed in the background by the server. Emacs in terminal has a lot of annoyances in my experience as well.
paretoOptimalDev · 2022-09-30 18:28
You can use a wrapper script to exec within the docker container, but I think ideally the REPL would support tramp.
paretoOptimalDev · 2022-09-30 18:32
> Tramp/LSP/Projectile and Tramp always started crawling and be pretty much unusable. Replace lsp-mode and projectile with eglot and project.el and you'll likely have 0 problems with tramp. One advantage of using "closer to emacs" packages written by people that have contributed to emacs is they take conventions like working with tramp into account and re-use of other core emacs facilities into account more.
servingwater · 2022-09-30 18:46
Thanks for the tip. I'll try that.
astoff1 · 2022-09-30 18:59
The big issue with remotes language servers is the latency of the SSH connection, so running the server in a (local) container should be fine. I didn't quite understand the 1m30 vs 20s scenarios. But I think on a Mac M1 the container has to emulate the x86 professor and the Linux kernel, no? So it's always going to be slow? Just guessing here.
servingwater · 2022-09-30 21:26
And to be fair I think that is how vscode remote does, too. I actually install the extensions like lsp and others on the server.
sirsamsai · 2022-09-30 22:11
Of course none of this *forces* me to edit remote files. If I wanted, I could do what you suggest to do. But editing remote files in these scenarios is way more ergonomic than having to juggle between editing the files and then moving them over to another host to try them out. Iteration time is significantly lowered when you don't have to edit your code blind and can get immediate feedback about potential problems (library is missing, path is incorrect, wrong environment variables are set, etc). Doing the edit-rsync-test cycle means a introducing an extra step that causes a context switch and which may introduce errors. Having to solve obvious issues caused by environment differences or unchecked assumptions increases frustration, which combined with frequent context switching means easily drifting to other tasks or entirely unproductive activities, like browsing the web. So, why accept a sub-optimal workflow? I can keep my edit-test cycle tight, I can work on my stuff in an environment that is supposed to work in a particular way and have the necessary tools and libraries installed and provides the necessary capabilities. Also, sometimes in my line of work (R&D), it is simply enough to get some code to run correctly once in a specific test environment. So, it could be completely reasonable for me to write some code via remote editing on a specific server, get it to run, pull the results out and throw the code on Git for it to probably never be touched again. So, transferring that kind of code between two machines would frankly be kind of a pointless waste of time.
nieuweyork · 2022-10-01 00:17
I find that it’s faster to build and deploy while developing from a machine in my employer’s cloud infra. Because I can’t use lsp over tramp I now use git to transfer the files over ssh. Which works ok, but it would be way smoother if I could just edit the files remotely. The other case when I want to do this is when I’m on a low bandwidth connection. There again I like to avoid pulling binary anything to my local machine.
[deleted] · 2022-10-01 02:48
[removed]
martin4233 · 2022-10-01 16:11
Here are my two cents: My setup keeps the source code and LSP locally for a one million-line C++ project, which works well. For syncing I use unison (https://www.cis.upenn.edu/~bcpierce/unison/), which I can only recommend. It sits in the background and watches the local filesystem and syncs each file immediately after saving. Compilation is done remotely, triggered via compilation-mode, so all output and compilation errors show up in Emacs. I start unison from within Emacs once and afterwards basically forget about it.
astoff1 · 2022-10-01 17:26
FTR, there are many other options to do the syncing, from Unison (mentioned in another reply) to packages like ssh-depoy to simply running `git ls-files -c -o --exclude-standard | rsync -avRP --files-from=- . <destination>` (which is what I do, in a little Emacs command that relies on `async-shell-command`).
astoff1 · 2022-10-01 17:33
My projects are not that large, but I just use `git ls-files -c -o --exclude-standard | rsync -avRP --files-from=- . <destination>` and it works fine. I call this from Emacs using a command that computes the destination automatically for me and runs the command asynchronously. I call it manually since it doesn't bother me too much, but I could also do something slightly cleverer in `after-save-hook`. Anyway, I don't know why the other responses here became so... passionate. An approach like yours seems more natural to me, and I was trying to figure out if the alternative, which is to do everything remotely, is more of a preference or a hard necessity. For the most part, it seems to be the former.
astoff1 · 2022-10-01 17:37
> Code which is under NDA and is not allowed to be stored in personal machines. This is interesting, I've never heard of such a thing. I have such restrictions on the data that I need to do the computations, but not on the code itself.
HeyItsLP · 2022-10-01 18:43
At any big tech company you are expected to keep internal code only on provided machines, and whether or not using tramp is breaking that can be debated, it is something that \~might\~ be done.
paretoOptimalDev · 2022-10-01 18:44
> I didn't quite understand the 1m30 vs 20s scenarios. But I think on a Mac M1 the container has to emulate the x86 professor and the Linux kernel, no? Not if everything is an aarch64-darwin executable like it was here. The problem was the docker volumes being that much slower.
FreeAd7233 · 2022-10-01 19:05
In my perspective, the most inconvenient part of using emacs directly in remote server is the installation. It is hard to build a statically linked binary for eMacs so that I can bring it to anywhere without resorting to package managers, and usually you can’t have the latest version. This is the thing make using eMacs directly in remote less attractive. And in contrast to neovim, neovim has statically linked binary (only depend on libc) in their official github release, so it is easy to run neovim anywhere on any remote server. And vim, the de facto of Linux distribution, no need to say more. Vanilla users are highly relying on modifiers, so the terminal swallows too much ctrl keys and alt keys may be a issue. But I am using evil so this is not a problem to me.
servingwater · 2022-11-11 18:35
Due to your suggestions I have given Emacs and Tramp another shot. And I'm glad I did. I think this time it may have stuck. project.el did make a huge difference for me over Tramp. And perhaps Tramp itself has improved as well but it is very usable right now. Thank you very much!
hhnever · 2022-11-12 00:44
I think Projectile does not consider tramp during design and it has so many issues with tramp: https://github.com/bbatsov/projectile/issues?q=tramp