dominikh / go-mode.el

Emacs mode for the Go programming language
BSD 3-Clause "New" or "Revised" License
1.38k stars 211 forks source link

go-mode vs. go-ts-mode (included with Emacs) #440

Open stapelberg opened 3 months ago

stapelberg commented 3 months ago

Hey @dominikh and community, also cc @aclonegeek (author of go-ts-mode)

I recently learnt that Emacs 29 includes tree-sitter: https://www.masteringemacs.org/article/how-to-get-started-tree-sitter

Notably, aside from tree-sitter itself, Emacs 29 also includes a go-ts-mode package which provides tree-sitter based syntax highlighting for Go code.

In fact, I found blog posts that outline how to set up Emacs for Go development (e.g. https://magnus.therning.org/2023-11-16-using-the-golang-mode-shipped-with-emacs.html) that don’t use go-mode.el at all anymore.

This got me wondering: Is some sort of transition underway from go-mode to go-ts-mode? Or are both supposed to coexist indefinitely? What reasons might one have to prefer go-mode over go-ts-mode on Emacs 29+? It would probably be good to eventually explain this in the README, but I figured I’d ask here first.

Thanks in advance

dominikh commented 3 months ago

Last time I checked (which was around the release of 29), go-ts-mode was a pretty barebones wrapper around tree-sitter that didn't provide any extra functionality. Admittedly, in the days of LSP, there's less functionality the mode itself needs to provide, but go-mode still offers functionality that LSP doesn't cover, such as support for displaying Go coverage profiles, integration with the Go playground, and ironically a set of movement functions (go to arguments, imports, etc) that would've been a lot easier to implement using tree-sitter... Furthermore, go-mode's indentation is an almost perfect match to gofmt, while go-ts-mode's is far from correct on any of the more complex cases.

My plans for go-mode are a complete rewrite, using tree-sitter for any functionality that depends on syntax. I have local work to that end, which is 80% complete. I temporarily stopped work on that 8 months ago, primarily because I was blocked on bugs in Emacs's tree-sitter integration. I'll have to check if the fixes for those have been released yet. I will merge and release that rewrite once I feel comfortable making tree-sitter a hard dependency. I'm not inclined to maintain both the old and the new mode concurrently.

As for coexistence: I reckon the two will coexist indefinitely, even after my rewrite. I am not willing to contribute my mode upstream, and Emacs is unlikely to drop an existing mode of theirs in favour of a 3rd party one.

stapelberg commented 3 months ago

Thanks for your explanation! It would probably be good to add a comparison table to the README so that users know when to reach for go-mode.el and when the builtin go-ts-mode is sufficient.

For example, I wasn’t aware of any of the advanced features you mentioned :)

dominikh commented 3 months ago

I'm not sure how many people would see that, considering the README already lists all of those features: https://github.com/dominikh/go-mode.el?tab=readme-ov-file#features

stapelberg commented 3 months ago

Sorry for not checking the README more closely before writing my message.

I’m sure I must have seen it before, though, so I thought a little bit about why nothing seems to have stuck. To hopefully contribute something positive, here are a few suggestions for improvements to the feature list:

  1. Turn it from a list into a table, with columns [function, key binding, description]. That will make it much easier to scan visually.
  2. I might reorder items such that the tablestakes features are at the very top (gofmt-before-save, organize-imports, godef), then the various integrations (godoc, playground, coverage), then maybe the jump commands as its own group.
    • IIUC, gofmt, organize-imports and godef are also possible with eglot in go-ts-mode, but go-mode offers more functionality (changing the binary, adding imports with tab completion). This would be worthwhile to point out.