go-mode.el
go-mode.el copied to clipboard
Fully support TRAMP
Go-mode should probably support TRAMP, i.e. be able to run commands such as godef on remote files.
What isn't clear to me yet is whether the commands should be executed locally or remotely, how to handle programs that need the entire GOPATH, and whether this should be configurable or not. My intuition tells me that we'd be able to run gofmt locally, but need to run everything else on the remote machine (including gofmt replacements such as goimports).
This issue acts as an umbrella issue for #46, #247, #207 and #239. I will likely draw input and inspiration from these, but arrive at my own overall implementation.
https://www.gnu.org/software/emacs/manual/html_node/tramp/Remote-processes.html https://www.gnu.org/software/emacs/manual/html_node/elisp/Synchronous-Processes.html
Just my 2c, when on a TRAMP buffer it makes sense to run all commands remotely. Otherwise there might be versions or dependencies compatibility issues.
Personally, I am using emacs on a local laptop, connecting to different hosted vms. Each could have different versions of commands or libraries. When I am on a remote buffer, I expect all the commands to run in the context of that buffer.
However, I am really new to go language, so I am not well versed in all the potential problems that we might face.
Running all commands remotely would certainly be easier to implement. I guess the real question is: do people think of TRAMP as an alternative to ssh, or as an alternative to networked file systems?
I think of tramp as a replacement to the ssh/vim combo. I also think it will be quite difficult and cumbersome to use tramp as a "networked file system". I guess if someone would want a "networked filed system" they should simply something like sshfs instead of tramp.
I would definitely go the "alternative to ssh" route. Not only should it be much simpler to implement, but you also wont waste your time building another solution to an already solved problem (such as sshfs, cifs, nfs etc).
I too think that the commands should all be run remotely. This provides an obvious form of consistency: a command is guaranteed to work exactly as if run locally on the remove machine.
In general the typical strategy to support remote filenames is:
- Run all processes remotely using
process-file
,start-file-process
, etc. - Such remote processes accept local filenames on the remote system. Use
file-local-name
for that. - If the remote processes emit filenames, then either Emacs can convert them to Emacs remote filenames automatically (e.g. in compilation buffers), or you need to do it manually using
(concat (file-remote-p ...) local-name)
. - If you need a temporary file on the remote machine, use
make-nearby-temp-file
.
That way you can support all kinds of local and special filenames, not just TRAMP.
Jumping in on this one... I definitely get frustrated that it's easy for me to save changes to a remote go box (in my case, a Raspberry PI) but I get "GOCODE PANIC" quite often and autocomplete bombs. This becomes a bigger problem given that my client is generally always a Mac or a Windows box, but where I compile+run golang code is almost always some variant of Linux.
The Darwin arch is obviously not gonna work for quite a number of C libraries that only run on certain arches such as arm6, so running some commands locally would present issues given if libraries would be needed to resolve as if they were local but it's not compilable locally.
What I have been doing to get around this problem is using a Raspberry PI 3B+ which is barely fast enough to compile Go programs on, and then rexec them from local. If it's a small tweak to a file that I need I edit from TRAMP and ignore the warnings (say to just some parms or a config file). If I'm writing out logic I use ssh/mosh into the faster Pi machine to develop.
The code I'm working on right now happens to be running on a Pi Zero W which is way too underpowered to run the gocompiler (it can run, but it takes aaaaaages for it to run). Once I have it in a happy state on a bigger Raspberry PI then I use TRAMP to copy it over to the little Pi Zero to test on "real hardware".
Some patches can be found here: https://yrh.dev/blog/remote-editing-go-code-with-emacs/
Is it still not possible to use go-mode over tramp?
I have also just now encountered this issue when trying to move from Emacs-over-X11-forwarding to Emacs-with-TRAMP.
There’s no question in my mind that the model should be “run all commands remotely”, as many others have written, too.
@dominikh What’s the status of this issue? Is it something where you’d be accepting pull requests now? Thanks.
@stapelberg I would probably accept pull requests for better TRAMP support, yes. However, what's missing is an actual list of things that fail, why they fail, and how we can fix things for everything in one go, not patching issues as we find them.
But I would've also expected this problem to become irrelevant by now. As far as I understand it, LSPs can be run over TRAMP, and go-mode + gopls doesn't need to execute any external commands other than gopls itself.
Thanks for the pointer. Time to evaluate what I use go-mode for, I suppose :)
I first looked into uninstalling go-mode entirely, but then eglot can’t figure out which language server to start in fundamental-mode.
Then, I looked at my go-related configuration. I had the following line in my config:
(add-hook 'before-save-hook 'gofmt-before-save)
I now replaced the line with:
(add-hook 'before-save-hook 'eglot-format)
That seems to only give me gofmt, not goimports. For that, I’ll take a look at following https://github.com/golang/tools/blob/master/gopls/doc/emacs.md#organizing-imports-with-eglot
That seems to address my immediate need. Thanks again, and hopefully this hint helps others, too.