Now that I have installed Emacs 29.1, I needed to get it set up for Go development for a project. I was interested in taking advantage of both the new Tree-Sitter integration, and the new Eglot language server client. However, they were mildly tricky to set up! Here is what I did.
Configuring Tree-Sitter for Go
If you follow the excellent How to Get Started with Tree-Sitter instructions from Mickey Peterson, you will have a great head-start on getting Tree-Sitter working for most of your favorite languages (and probably Java, too). However, those instructions didn’t cover everything I needed for Go. When I tried running
M-x go-ts-mode, Emacs complained about a missing
gomod module. Baffling!
I couldn’t find any information in the Emacs documentation about where to find this missing module. I looked around on the net and found Camden Cheek’s tree-sitter-go-mod, and added that to my list of recipes. My
treesit-language-source-alist then looked like this:
Note that the package is named
go-ts-mode expects it to be named
gomod. I wish this were documented somewhere! In any case, I was then able to use
M-x treesit-install-language-grammar for both
M-x go-ts-mode worked!
After going through this process, I found Robert Enzmann’s post about automatically using Tree-Sitter. He has created the
treesit-auto package, now available on MELPA, that does most of this work for you. It is a much faster way of solving the
gomod mystery, so give it a shot!
Configuring Eglot for Go
In my Go project, I ran
M-x eglot and was immediately met with an error:
[eglot] Server reports (type=1): Error loading workspace folders (expected 1, got 0) failed to load view for file:///path/to/my/project: err: go command required, not found: exec: "go": executable file not found in $PATH: stderr:
I’ve got Go installed in
/usr/local/go/bin is definitely in my
exec-path variable in Emacs. It looked like Eglot wasn’t propagating
exec-path down to its subprocesses. How annoying! I did a quick search through the list of Eglot-related variables and the Eglot documentation and no solution seemed immediately forthcoming.
So I took the cheap way out and made a symlink. In my shell, I ran:
sudo ln -sf /usr/local/go/bin/go /usr/local/bin/go
It is a dumb trick, and I am sure there is a better way to solve it. Do you know of one? Please comment and let me know!
My exploration has revealed that there’s a lot of work left to do in the Emacs Tree-Sitter world. There are plenty of languages major modes that don’t yet have a
ts-mode equivalent, and plenty of others that still need a lot of work.
It’s too soon for me to say if this setup is preferrable to my previous configuration. But I am really looking forward to playing around with Eglot’s features and exploring the capabilities of Tree-Sitter.