go.md

  1---
  2title: Go
  3description: "Configure Go language support in Zed, including language servers, formatting, and debugging."
  4---
  5
  6# Go
  7
  8Go support is available natively in Zed.
  9
 10- Tree-sitter: [tree-sitter/tree-sitter-go](https://github.com/tree-sitter/tree-sitter-go)
 11- Language Server: [golang/tools/tree/master/gopls](https://github.com/golang/tools/tree/master/gopls)
 12- Debug Adapter: [delve](https://github.com/go-delve/delve)
 13
 14## Setup
 15
 16We recommend installing gopls via go's package manager and not via Homebrew or your Linux distribution's package manager.
 17
 181. Make sure you have uninstalled any version of gopls you have installed via your package manager:
 19
 20```sh
 21# MacOS homebrew
 22brew remove gopls
 23# Ubuntu
 24sudo apt-get remove gopls
 25sudo snap remove gopls
 26# Arch
 27sudo pacman -R gopls
 28```
 29
 302. Install/Update `gopls` to the latest version using the go module tool:
 31
 32```sh
 33go install golang.org/x/tools/gopls@latest
 34```
 35
 363. Ensure that `gopls` is in your path:
 37
 38```sh
 39which gopls
 40gopls version
 41```
 42
 43If `gopls` is not found you will likely need to add `export PATH="$PATH:$HOME/go/bin"` to your `.zshrc` / `.bash_profile`
 44
 45## Inlay Hints
 46
 47Zed sets the following initialization options for inlay hints:
 48
 49```json
 50"hints": {
 51    "assignVariableTypes": true,
 52    "compositeLiteralFields": true,
 53    "compositeLiteralTypes": true,
 54    "constantValues": true,
 55    "functionTypeParameters": true,
 56    "parameterNames": true,
 57    "rangeVariableTypes": true
 58}
 59```
 60
 61to make the language server send back inlay hints when Zed has them enabled in the settings.
 62
 63Use
 64
 65```json
 66"lsp": {
 67    "gopls": {
 68        "initialization_options": {
 69            "hints": {
 70                // ....
 71            }
 72        }
 73    }
 74}
 75```
 76
 77to override these settings.
 78
 79See [gopls inlayHints documentation](https://github.com/golang/tools/blob/master/gopls/doc/inlayHints.md) for more information.
 80
 81## Code Lens
 82
 83Zed enables the `test` code lens for `gopls` by default. This shows "run test" and "run benchmark" links above `Test` and `Benchmark` functions in `*_test.go` files. To use them, enable the `code_lens` setting:
 84
 85```json [settings]
 86{
 87  "code_lens": "on"
 88}
 89```
 90
 91You can override the default code lens settings in your `settings.json`:
 92
 93```json [settings]
 94{
 95  "lsp": {
 96    "gopls": {
 97      "initialization_options": {
 98        "codelenses": {
 99          "test": true,
100          "generate": true,
101          "regenerate_cgo": true,
102          "tidy": true,
103          "upgrade_dependency": true,
104          "vendor": true
105        }
106      }
107    }
108  }
109}
110```
111
112See [gopls code lenses documentation](https://go.dev/gopls/codelenses) for more information.
113
114## Debugging
115
116Zed supports zero-configuration debugging of Go tests and entry points (`func main`) using Delve. Run {#action debugger::Start} ({#kb debugger::Start}) to see a contextual list of these preconfigured debug tasks.
117
118For more control, you can add debug configurations to `.zed/debug.json`. See below for examples.
119
120- [Delve configuration documentation](https://github.com/go-delve/delve/blob/master/Documentation/api/dap/README.md#launch-and-attach-configurations)
121
122### Debug Go Packages
123
124To debug a specific package, you can do so by setting the Delve mode to "debug". In this case "program" should be set to the package name.
125
126```json [debug]
127[
128  {
129    "label": "Go (Delve)",
130    "adapter": "Delve",
131    "program": "$ZED_FILE",
132    "request": "launch",
133    "mode": "debug"
134  },
135  {
136    "label": "Run server",
137    "adapter": "Delve",
138    "request": "launch",
139    "mode": "debug",
140    // For Delve, the program can be a package name
141    "program": "./cmd/server"
142    // "args": [],
143    // "buildFlags": [],
144  }
145]
146```
147
148### Debug Go Tests
149
150To debug the tests for a package, set the Delve mode to "test".
151The "program" is still the package name, and you can use the "buildFlags" to do things like set tags, and the "args" to set args on the test binary. (See `go help testflags` for more information on doing that).
152
153```json [debug]
154[
155  {
156    "label": "Run integration tests",
157    "adapter": "Delve",
158    "request": "launch",
159    "mode": "test",
160    "program": ".",
161    "buildFlags": ["-tags", "integration"]
162    // To filter down to just the test your cursor is in:
163    // "args": ["-test.run", "$ZED_SYMBOL"]
164  }
165]
166```
167
168### Build and debug separately
169
170If you need to build your application with a specific command, you can use the "exec" mode of Delve. In this case "program" should point to an executable,
171and the "build" command should build that.
172
173```json [debug]
174[
175  {
176    "label": "Debug Prebuilt Unit Tests",
177    "adapter": "Delve",
178    "request": "launch",
179    "mode": "exec",
180    "program": "${ZED_WORKTREE_ROOT}/__debug_unit",
181    "args": ["-test.v", "-test.run=${ZED_SYMBOL}"],
182    "build": {
183      "command": "go",
184      "args": [
185        "test",
186        "-c",
187        "-tags",
188        "unit",
189        "-gcflags\"all=-N -l\"",
190        "-o",
191        "__debug_unit",
192        "./pkg/..."
193      ]
194    }
195  }
196]
197```
198
199### Attaching to an existing instance of Delve
200
201You might find yourself needing to connect to an existing instance of Delve that's not necessarily running on your machine; in such case, you can use `tcp_arguments` to instrument Zed's connection to Delve.
202
203```json [debug]
204[
205  {
206    "adapter": "Delve",
207    "label": "Connect to a running Delve instance",
208    "program": "/Users/zed/Projects/language_repositories/golang/hello/hello",
209    "cwd": "/Users/zed/Projects/language_repositories/golang/hello",
210    "args": [],
211    "env": {},
212    "request": "launch",
213    "mode": "exec",
214    "stopOnEntry": false,
215    "tcp_connection": { "host": "127.0.0.1", "port": 53412 }
216  }
217]
218```
219
220In such case Zed won't spawn a new instance of Delve, as it opts to use an existing one. The consequence of this is that _there will be no terminal_ in Zed; you have to interact with the Delve instance directly, as it handles stdin/stdout of the debuggee.
221
222## Go Mod
223
224- Tree-sitter: [camdencheek/tree-sitter-go-mod](https://github.com/camdencheek/tree-sitter-go-mod)
225- Language Server: N/A
226
227## Go Sum
228
229- Tree-sitter: [amaanq/tree-sitter-go-sum](https://github.com/amaanq/tree-sitter-go-sum)
230- Language Server: N/A
231
232## Go Work
233
234- Tree-sitter:
235  [tree-sitter-go-work](https://github.com/d1y/tree-sitter-go-work)
236- Language Server: N/A